Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.
Manacher 线性算法
利用一个辅助数组 arr[n],其中 arr[i] 记录的是以 str[i] 为中心的回文子串长度。当计算 arr[i] 的时候,arr[0...i-1] 是已知并且可被利用的。Manacher 核心在于:用 mx 记录之前计算的最长的回文子串长度所能到达的最后边界,用 id 记录其对应的中心,可以利用回文子串中的回文子串信息。
假设 id 与 mx 已经得出,当计算以 str[i] 为中心回文子串长度时,因为已经可以确定绿色部分已经是回文子串了,所以可以利用以 str[j] 为中心回文子串长度即 arr[j]。在上图的情况下,所以可以从箭头所指出开始比较。还有一种情况:
class Solution {
public:
string longestPalindrome(string s) {
string sc;
sc += '#';
//add '#'
for(int i=0; i<s.length(); ++i){
sc += s[i];
sc += '#';
}
vector<int> p(sc.length()); //store the pre information
p[0]=1;
int id = 0; //mid
int mx = 0; //depth
int max = 0;
int index = 0;
for(int i=0;i<sc.length();++i){
if(mx>i){
p[i]=min(p[2*id-i],mx-i);
}
else
p[i]=1;
while(sc[i+p[i]]==sc[i-p[i]]&& i-p[i] >=0 &&i+p[i]<sc.length())
p[i]++;
if(p[i]+i>mx){
id = i;
mx = p[i]+i;
}
if(p[i]>max){
max = p[i];
index = i;
}
}
//delete "#"
string cret = sc.substr(index-p[index]+1,2*p[index]-1);
string ret;
for(int i=0;i<cret.length();++i){
if(cret[i]=='#')
continue;
else
ret += cret[i];
}
return ret;
}
};