LeetCode(Longest Palindromic Substring)

Manacher算法,时间复杂度为O(n)。

预处理:
原串s:aaaba
转换后得到的串t:#a#a#a#b#a#
引入辅助数组vec,vec[i]表示以t[i]为中心的最长回文串的半径:
t:#a#a#a#b#a#
vec:12343214121
vec的性质:vec[i]-1=以t[i]为中心的最长回文串在原串s中的长度。
证:在最长回文串中,#的个数=原串s的字符的个数+1。

vec的计算:
显然vec[0]=1,当i>=1时,我们根据vec[0],…,vec[i-1]计算vec[i]。
设xm为当前最长回文子串的右端点的最大值的位置,分两种情况:
(1)i < xm
设j为i关于x的对称位置,j=2x-i:
2x-xm < j < x < i < xm
如果vec[j] < xm-i+1,vec[i]=vec[j];
如果vec[j]>=xm-i+1,从xm+1开始往右匹配,直到失配,然后更新x,xm,vec[i]。
(2)i>=xm
从i+1开始往右匹配,直到失配,然后更新x,xm,vec[i]。

class Solution {
public:
    string longestPalindrome(string s) {
        if(s.size()<=1)return s;
        string t,result;
        for(int i=0;i<s.size();++i)
        {
            t+='#';
            t+=s[i];
        }
        t+='#';
        vector<int> vec(t.size());
        vec[0]=1;
        int x=0,xm=0,maxRadius=1,maxIndex=0;
        for(int i=1;i<t.size();++i)
        {
            if(i<xm)vec[i]=min(vec[2*x-i],xm-i+1);
            else vec[i]=1;
            while(i-vec[i]>=0&&i+vec[i]<t.size()&&t[i-vec[i]]==t[i+vec[i]])++vec[i];
            if(i+vec[i]-1>xm)
            {
                xm=i+vec[i]-1;
                x=i;
            }
            if(vec[i]>maxRadius)
            {
                maxRadius=vec[i];
                maxIndex=i;
            }
        }
        for(int i=maxIndex-maxRadius+2;i<=maxIndex+maxRadius-2;i+=2)result+=t[i];
        return result;
    }
};

http://blog.csdn.net/dyx404514/article/details/42061017

你可能感兴趣的:(LeetCode(Longest Palindromic Substring))