5.Longest Palindromic Substring

class Solution {
public:
    string longestPalindrome(string s) {
        if (s.empty()) return "";
        int dp[s.size()][s.size()] = {0}, left = 0, right = 0, len = 0;
        for (int i = 0; i < s.size(); ++i) {
            dp[i][i] = 1;
            for (int j = 0; j < i; ++j) {
                dp[j][i] = (s[i] == s[j] && (i - j < 2 || dp[j + 1][i - 1]));
                if (dp[j][i] && len < i - j + 1) {
                    len = i - j + 1;
                    left = j;
                    right = i;
                }
            }
        }
        return s.substr(left, right - left + 1);
    }
};
class Solution {
public:
    string longestPalindrome(string s) 
    {
        //重新构造新的字符串t,这样新的字符串的字符个数始终为奇数个
        string t="&#";  //加&是为了防止越界,后面自带'\0'
        for(int i=0;i<s.size();++i)
        {
            t+=s[i];
            t+="#";
        }
        //新建P[i]用来存放以t[i]字符为中心的回文子串的半径
        vector<int> P(t.size(),0);

        int mx=0;   //是回文串能延伸到的最右端位置
        int iD=0;   //每个回文串的中间点
        int resLen=0,resCenter=0;
        for(int i=1;i<t.size();++i)
        {   
            /*当i<mx时,能对称取值得下标,当半径小于mx-i时,就是本身,
             *大于则只能取mx-iD,超过的部分只能++的比较。当i>mx时,只能++的比较。*/
            p[i]=mx>i?min(p[2*iD-i],mx-i):1;    

            while(t[i+P[i]]==t[i-P[i]])
                ++P[i];           //以i点为中心的P[i]的最大值

            if(mx<i+P[i])           //重新选择中心点并改变mx
            {
                mx=i+P[i];
                iD=i;
            }
            if(resLen<P[i])         //记录最大的半径和对应的中间点的值
            {
                resLen=P[i];
                resCenter=i;
            }

        }
        return s.substr((resCenter-resLen)/2,resLen-1);
    }
 };
posted @ 2019-04-08 17:02  JohnRed  阅读(107)  评论(0编辑  收藏  举报