首页 > 其他分享 >5. 最长回文子串

5. 最长回文子串

时间:2024-12-16 14:13:41浏览次数:4  
标签:子串 string int i1 str ans 最长 dp 回文

  1. 题目链接

  2. 解题思路:最长回文子串问题,首先要将原字符串扩充,比如abba,暴力是以每个字符s[i],左右两边扩,如果是abba,得不到最优解,扩充成#a#b#b#a#,就不会有问题,最优解是manacher算法。

    • 假设s[i]扩充的区域是[x, y],是目前便利到的,最远的距离,我们称i为回文中心Cy为回文最远右边界R,同时,还用数组记录每个点,扩充的回文半径dp[i],关系是x == i - dp[i] + 1, y == i + dp[i] - 1
    • 具体的步骤见代码中的注释
  3. 代码

    class Solution {
    public:
        void addChar(const string &s, string &new_str) {
            for (int i = 0; i < s.size(); ++i) {
                new_str.push_back('#');
                new_str.push_back(s[i]);
            }
            new_str.push_back('#');
        }
        string longestPalindrome(string s) {
            string str = "";
            addChar(s, str);
            int C = 0;
            int R = 0;
            int n = str.size();
            vector<int> dp(n, 0);
            dp[0] = 1;
            int ans = 0;
            int ans_index = -1;
            for (int i = 1; i < n; ++i) {
                if (i > R) {
                    int l = i - 1;
                    int r = i + 1;
                    while(l >= 0 && r < n) {
                        if (str[l] == str[r]) {
                            l--;
                            r++;
                        } else {
                            break;
                        }
                    }
                    if (r - 1 > R) {
                        R = r - 1;
                        C = i;
                    }
                    dp[i] = r - i;
                    if (dp[i] > ans) {
                        ans = dp[i];
                        ans_index = i;
                    }
                    
                } else {    // i 在R内   找到i的对称点
                    int i1 = 2 * C - i;
                    int L = 2 * C - R;
                    if (i1 - dp[i1] + 1 > L) {    // 彻底在内
                        dp[i] = dp[i1];
                    } else if(i1 - dp[i1] + 1 == L) {   // 扩
                        int r = R + 1;
                        int l = 2 * i - r;
                        while(l >= 0 && r < n) {
                            if (str[l] == str[r]) {
                                r++;
                                l--;
                            } else {
                                break;
                            }
                        }
                        dp[i] = r - i;
                        if (r - 1 > R) {
                            R = r - 1;
                            C = i;
                        }
                        if (dp[i] > ans) {
                            ans = dp[i];
                            ans_index = i;
                        }
                    } else {
                        dp[i] = R - i + 1;
                    }
                }
            }
            string ans_str = "";
            for (int i = ans_index - ans + 1; i <= ans_index + ans - 1; i++){
                if (str[i] != '#') {
                    ans_str.push_back(str[i]);
                }
            }
            return ans_str;
        }
    };
    

标签:子串,string,int,i1,str,ans,最长,dp,回文
From: https://www.cnblogs.com/ouyangxx/p/18609959

相关文章

  • 代码随想录算法训练营第四十六天|leetcode647. 回文子串、leetcode516.最长回文子序列
    1leetcode647.回文子串题目链接:647.回文子串-力扣(LeetCode)文章链接:代码随想录视频链接:动态规划,字符串性质决定了DP数组的定义|LeetCode:647.回文子串哔哩哔哩bilibili思路:嘿,看不懂有一点,看解析吧1.1视频后的方法其实看完视频以后,感觉这个题目真的不难,我想到了二维......
  • 代码随想录算法训练营第四十四天|leetcode1143.最长公共子序列、leetcode1035.不相交
    1leetcode1143.最长公共子序列题目链接:1143.最长公共子序列-力扣(LeetCode)文章链接:代码随想录视频链接:动态规划子序列问题经典题目|LeetCode:1143.最长公共子序列哔哩哔哩bilibili思路:其实我比较清楚的是和上面一道题目的思路,差不太多,但是我不知道非连续的位置应该如何......
  • 3. 无重复字符的最长子串
    题目链接解题思路:最长子串问题,考虑,以i开头的结果如何,以i结尾的结果如何,最终结果必定在其中。本题使用以i开头的结果如何,我们求出所有的「以i开头的最长子串」,再求出最长的即可。求「以i开头的最长子串」,最简单的暴力即可,那么怎么加速呢?我们在求「以i-1开头的最长子长串时......
  • 题海拾贝:LCR018.验证回文串
               Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路!我的博客:<但凡.我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》欢迎点赞,关注!1、题目2、2、题解         这个题如果没有空格和符号的话,那就直接双指......
  • 【力扣算法】234.回文链表
    快慢指针:一个指针走两步,一个指针走一步,当快指针走到链表末尾时,慢指针走到中间位置。 逆转链表:根据指针位置分成两个表,逆转第二个表。按序判断就可以,如果是相同就是回文,反之就不是。快慢指针能找链表中间,也可以判断链表是否有环/***Definitionforsingly-linkedlist.......
  • 【算法】【字符串】关联子串
    1 题目给定两个字符串str1和str2,如果字符串str1中的字符,经过排列组合后的字符串中,只要有一个字符串是str2的子串,则认为str1是str2的关联子串。若str1是str2的关联子串,请返回子串在str2的起始位置;若不是关联子串,则返回-1。输入描述:输入两个字符串,分别为题目中描述的str1、str......
  • leetcode 866. 回文质数
    866.回文质数想着开大数组,用质数筛选的方法。但是开大数组超内存了......
  • 代码随想录算法训练营第四十六天|LeetCode647.回文串、LeetCode516.最长回文子序列
    前言打卡代码随想录算法训练营第49期第四十六天 ε(*′・∀・`)з゙首先十分推荐学算法的同学可以先了解一下代码随想录,可以在B站卡哥B站账号、代码随想录官方网站代码随想录了解,卡哥清晰易懂的算法教学让我直接果断关注,也十分有缘和第49期的训练营大家庭一起进步。LeetCode647......
  • leetcode 125. 验证回文串
    125.验证回文串二刷,用时3ms,内存9.81MB一定要注意,是移除所有除了数字、字母以外的字符classSolution{public://'a'-'A'=32boolisPalindrome(strings){intleft=0,right=s.size()-1;while(left<right){while(left<......
  • 编程题-最长公共前缀
    题目:编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。示例1:输入:strs=["flower","flow","flight"]输出:"fl"示例2:输入:strs=["dog","racecar","car"]输出:""解释:输入不存在公共前缀。解题:依......