最長迴文子串--馬拉車(?)

每一個迴文串必定有一箇中心,然而若是這個串長度是偶數,它的中心是空的,因此咱們把長度爲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;
}
相關文章
相關標籤/搜索