leetcode 5 最长回文子串

Posted xiying159

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 5 最长回文子串相关的知识,希望对你有一定的参考价值。

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:

输入: "cbbd"
输出: "bb"

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  

解法1:最长公共子串

容易想到,回文意味着将这个字串反转,回文的部分一定是公共子串。

子串是一种动态规划的思路。这里借用别人的说明,很详细:

技术图片

但是这里依然有着一些区别:如果存在abcde...edcba的字串,那么abcde会被认为回文。所以我们需要二次检测来筛除这种问题。

int res[1005][1005];//这个涉及栈的大小问题,本机上开在函数内会超界。

class Solution {
public:
    string longestPalindrome(string s) {
        string sraw=s;
        reverse(s.begin(),s.end());//反转字串
        int len=s.length();
        int maxlen=0;//最大长度
        string ans;//最大回文子串
        for(int i=0;i<len;i++)
        {
            for(int j=0;j<len;j++)
            {
                if(s[i]==sraw[j])
                {
                    res[i+1][j+1]=res[i][j]+1;
                    if(res[i+1][j+1]>maxlen)
                    {
                        //这里二次判断是否回文。
                        string tmpans=s.substr(i-res[i+1][j+1]+1,res[i+1][j+1]);
                        string tmpansraw=tmpans;
                        reverse(tmpans.begin(),tmpans.end());
                        if(tmpansraw==tmpans)
                        {
                            maxlen=res[i+1][j+1];
                            ans=tmpans;
                        }
                    }
                }
                else res[i+1][j+1]=0;
            }
        }
        return ans;
    }
};  

 

解法2:动态规划。

思路是:遍历字串,然后初始化长度为1和长度为2的回文串。

在回文串的基础上,向左、向右分别多取一个字符,如果相等则构成新的回文串,更新结果。

int res[10050][10050];//不知道为什么1005过不了。。在本机是能过的

class Solution {
public:
    string longestPalindrome(string s) {
        memset(res,0,10050*10050);
        int len=s.length();
        string ans=s.substr(0,1);
        int maxlen=1;
        for(int i=0;i<len;i++)//遍历
        {
            //初始化一个字符的回文串
            int a=i;
            int b=i;
            res[a][b]=1;
            while(a>0&&b<len-1&&res[a][b]==1)//回文且可以向左、向右扩展
            {
                a--;b++;
                if(s[a]==s[b]) res[a][b]=1;//相同则标记回文
                if(b-a+1>maxlen&&res[a][b]==1)//更新结果
                {
                    maxlen=b-a+1;
                    ans=s.substr(a,b-a+1);
                }
            }    
            //初始化两个字符的回文串
            a=i;
            b=i+1;
            if(s[a]==s[b]) res[a][b]=1;
            if(2>maxlen&&res[a][b]==1)
            {
                maxlen=2;
                ans=s.substr(a,2);
            }
            while(a>0&&b<len-1&&res[a][b]==1)
            {
                a--;b++;
                if(s[a]==s[b]) res[a][b]=1;
                if(b-a+1>maxlen&&res[a][b]==1)
                {
                    maxlen=b-a+1;
                    ans=s.substr(a,b-a+1);
                }
            }

        }
        return ans;
    }
};

  

解法3:Manacher 算法

这个题解提供的我从没见过的算法……有空我会补上。

 

写给自己:

1.基础要牢。string的基本操作都忘了很多。

2.栈的知识,栈的默认大小为2M或1M,全局才能开到2G。

3.边界条件是最容易犯的错,尽量考虑周到来避免。

以上是关于leetcode 5 最长回文子串的主要内容,如果未能解决你的问题,请参考以下文章

leetcode-5 最长回文子串(动态规划)

LeetCode 5 最长回文子串

5-102-(LeetCode- 5) 最长回文子串

LeetCode 5. 最长回文子串(中)

LeetCode 5. 最长回文子串(中)

leetcode 5 最长回文子串