每一個迴文串必定有一箇中心,然而若是這個串長度是偶數,它的中心是空的,因此咱們把長度爲len的字符串變成長度2*len+1的字符串,每兩個字符中間補上一個相同的字符。ios
用r[i]表示以i爲中心的最長迴文半徑(若是字符兩邊不存在相同字符,r[i]=1)。記錄下該半徑對應的中心pos和半徑達到的最遠距離maxx,每當咱們遍歷一個i的時候,能夠找到它對於pos對稱的位置j,它的迴文串半徑必定大於等於j的迴文串半徑。若是j的迴文串半徑<2*pos-i+1,r[i]=r[j],反之,在maxx以外的距離可能也是i爲中心的迴文串的範圍,因此咱們一個個判斷,更新maxxspa
由於maxx在每一個位置最多被更新一次,因此複雜度O(n),看起來。。。很神奇?blog
#include<cstdio> #include<algorithm> #include<cstring> #include<string> #include<cmath> #include<iostream> using namespace std; char ss[1005]; char s[2010]; int r[2005];//最長迴文半徑 int main() { gets(ss+1); int len=strlen(ss+1); for(int i=1;i<=len;i++){ s[i*2]=ss[i]; s[i*2-1]='#'; } s[len*2+1]='#'; int pos=0,maxx=0; for(int i=1;i<=len*2+1;i++){ if(pos){ r[i]=min(maxx-i+1,r[pos*2-i]); while(i+r[i]<=len*2+1&&i-r[i]>0&&s[i+r[i]]==s[i-r[i]]) r[i]++; if(i+r[i]-1>maxx){ maxx=i+r[i]-1; pos=i; } } } return 0; }