题目: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;