算法原理
1.由于字符串在字符数为偶数或奇数时存在不同情况,我们在字符间插入字符串本身不存在的字符,例如:abcdefg中插入#,字符串变为#a#b#c#d#e#f#g#,变化后的字符串一定有奇数个字符。并且以p[n]表示以第n个字符为中心的回文串的半径,p[n]-1为最终第n个字符回文长度。
2.回文串的一个性质:假设存在一个足够长的回文串A,并且此回文以字符A[i]为中心,则根据对称的性质,以A[i-k]为中心的回文串长度 (此回文串的左右边界不超过回文串A的边界) 等于以A[i+k]为中心的回文串长度。
3.令m为以求的回文串的最右边界,i为以m为右边界的回文串的中心点。初始化m为1,i为1。
4.求p[n]:当n<m,且以n为中心的回文边界小于m:p[n]=p[2n-i]。
当n<m,且以n为中心的回文边界大于m:先令p[n]=m-n,在通过暴力解法判断未知部分。
当n>=m时:直接通过暴力求解。
核心代码:
int manacher(char* str,int n){
int p[n];
int maxl=0;
int m=1,co=0; p[0]=1;
int i;
for(i=1;i<n;i++){
if(i<m){
p[i]=min(p[2co-i],m-i);
}
else
p[i]=1;
while(str[i+p[i]]==str[i-p[i]]){p[i]++;}//暴力解法
if(i+p[i]>m){
m=i+p[i];
co=i;
}
maxl=max(maxl,p[i]-1);
}
return maxl;
}