码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode 5 最长回文子串

时间:2019-10-25 00:05:41      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:raw   bsp   长度   字符串   mamicode   基础上   更新   链接   答案   

给定一个字符串 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 最长回文子串

标签:raw   bsp   长度   字符串   mamicode   基础上   更新   链接   答案   

原文地址:https://www.cnblogs.com/xiying159/p/11735428.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!