题目:http://acm.hdu.edu.cn/showproblem.php?pid=3068
题意:给定一个长度不超过110000的字符串T,求它的最长回文子串。
求最长回文子串可以用后缀数组,扩展KMP算法,Manacher算法,其中Manacher算法无论时间还是编程复杂度都是最好的,
其时间复杂度为O(n)
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; const int N=200005<<1; char T[N]; //原字符串 char S[N]; //转换后的字符串 int R[N]; //回文半径 void Init(char *T) { S[0]='$'; int len=strlen(T); for(int i=0; i<=len; i++) { S[2*i+1]='#'; S[2*i+2]=T[i]; } } void Manacher(char *S) { int k=0,mx=0; int len=strlen(S); for(int i=0; i<len; i++) { if(mx>i) R[i]=R[2*k-i]<mx-i? R[2*k-i] : mx-i; else R[i]=1; while(S[i+R[i]]==S[i-R[i]]) R[i]++; if(R[i]+i>mx) { mx=R[i]+i; k=i; } } } int main() { while(~scanf("%s", T)) { Init(T); Manacher(S); int len=strlen(S); int ans=1; for(int i=0; i<len; i++) ans=R[i]>ans? R[i] : ans; printf("%d\n", ans-1); } return 0; }
另外,HDU3294也是一个很好的回文子串题目。
最长回文子串对应原串T中的位置:l = (i - R[i])/2; r = (i + R[i])/2 - 2;