马拉车算法,以优秀复杂度求解回文子串
我认为的关键:减少重复计算
用r表示当前已知回文子串右边界,id表示其中心的位置
显然我们当下求解的i应该再id右边
如果这个i在r的左边,那么显然在id的中心中,因该有一个关于i的对称点,并且因为位置的的原因,左边点的回文是已经被算出来了的,那样可以直接解决i到r部分的回文
然而更远的部分呢?就需要暴力扩展
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
string s,ss;
int id;
int r;
int p[110000001];
int Aimee;
int main(){
cin>>s;
int l=s.length();
for(int i=0;i<l;++i){
ss+='*';
ss+=s[i];
}
ss+='*';
s=ss;
l=s.length();
for(int i=0;i<l;++i){
if(i<=r){
p[i]=min(p[(id<<1)-i],r-i+1);
}
while(i-p[i]>=0&&i+p[i]<l&&s[i+p[i]]==s[i-p[i]]){
p[i]++;
}
if(p[i]+i>r){
r=p[i]+i-1;
id=i;
}
Aimee=max(Aimee,p[i]);
}
cout<<Aimee-1<<endl;
return 0;
}