感谢 鼻子很帅的猪 的讲解。
具体算法讲解请进:http://blog.163.com/zhaohai_1988/blog/static/2095100852012716105847112/
o(n) o(n)的复杂度,manacher确实碉堡了。
此外还有使用后缀数组的解法,不过 鼻子很帅的猪已经指出此种解法的bug
代码:
class Solution {
public:
string longestPalindrome(string s) {
int strlen = s.length();
if( strlen <= 1 )
return s;
//申请辅助空间的大小
strlen = strlen*2+1;
char *str = new char[strlen];
//p[i]表示以str[i]为对称中心回文串的长度
int *p = new int[strlen];
//id记录达到最大回文串时的对称中心位置,mx记录以id为中心的回文串的右边界,求以此边界左边的字符为对称中心的回文串长度时可以进行优化
int id = 0,mx = 1;
int i,j;
//对源字符串进行处理,在首、尾和每个字符后面插入字符#,这样处理可以避免分情况处理奇偶数的情况
for( i = 0; i < s.length(); i++ )
{
str[2*i] = '#';
str[2*i+1] = s[i];
}
//str[0] = 0;
str[2*i] = '#';
p[0] = 1;
for( i=1; i<strlen; i++)
{
// mx > i 表示以i为对称中心的回文串 对称中心落在id到mx之间,可以进行优化
if( mx > i )
{
p[i] = p[2*id-i] > (mx-i) ? (mx-i) : p[2*id-i];
}
else
{
p[i] = 1;
}
//对以i为中心的回文串的落在mx之外的部分进行统计
for( j = i+p[i]; j<strlen; j++ )
{
if( (2*i-j)>=0 && str[j] == str[2*i-j] )
p[i] +=1;
else
break;
}
//是否更新id
if( p[i] > p[id] )
{
id = i;
mx = id+p[id];
}
}
//return string(str,id-p[id]+1,2*p[id]-1);
return s.substr( (id-p[id]+1)/2, p[id]-1 );
}
};