标签:reads lse rac lan could ret print 序列 find
马拉车用于解决最长回文子串问题,重点是子串,而不是子序列,时间复杂度为O(n)。
解释一下变量的意义:
Len[i]数组去存第i个位置到mx位置的长度
id记录上一次操作的位置(这个操作可以看模板)
mx标记上一次的最长子串的最右端
模板:
1 void init() //这个是用来处理字符串的 2 { 3 memset(str,0,sizeof(str)); 4 int k=0; 5 str[k++]=‘$‘; 6 for(int i=0;i<len;++i) 7 str[k++]=‘#‘,str[k++]=s[i]; 8 str[k++]=‘#‘; 9 len=k; 10 } 11 int manacher() //求最长回文子串 12 { 13 Len[0]=0; 14 int sum=0; 15 int id,mx=0; 16 for(int i=1;i<len;++i) 17 { 18 if(i<mx) Len[i]=min(mx-i,Len[2*id-i]); 19 else Len[i]=1; 20 while(str[i-Len[i]]==str[i+Len[i]]) Len[i]++; 21 if(Len[i]+i>mx) 22 { 23 mx=Len[i]+i; 24 id=i; 25 sum=max(sum,Len[i]); 26 } 27 } 28 return (sum-1); 29 }
当我们要求的以第i个字符为回文字符串的中心的时候,如果i>=mx这个时候没法优化,就是判断(i-1)==(i+1)、(i-2)==(i+2)....一直这样找
看代码就是进行19行、再进行20行
如果i<mx的时候,这个时候
这个时候看一道模板题:
Input
Output
Sample Input
abcbabcbabcba abacacbaaaab END
Sample Output
Case 1: 13 Case 2: 6
这个时候要注意
不知道是这里memset(Len,0,sizeof(Len)); 导致的超时
还是
1 void init() 2 { 3 memset(str,0,sizeof(str)); 4 int k=0; 5 str[k++]=‘$‘; 6 for(int i=0;i<strlen(s);++i) 这个strlen导致的 7 str[k++]=‘#‘,str[k++]=s[i]; 8 str[k++]=‘#‘; 9 len=k; 10 }
正确代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<set> 6 using namespace std; 7 const int maxn=3000005; 8 const int INF=0x3f3f3f3f; 9 const int mod=998244353; 10 char str[maxn],s[maxn]; 11 int len,Len[maxn]; 12 void init() 13 { 14 memset(str,0,sizeof(str)); 15 int k=0; 16 str[k++]=‘$‘; 17 for(int i=0;i<len;++i) 18 str[k++]=‘#‘,str[k++]=s[i]; 19 str[k++]=‘#‘; 20 len=k; 21 } 22 int manacher() 23 { 24 Len[0]=0; 25 int sum=0; 26 int id,mx=0; 27 for(int i=1;i<len;++i) 28 { 29 if(i<mx) Len[i]=min(mx-i,Len[2*id-i]); 30 else Len[i]=1; 31 while(str[i-Len[i]]==str[i+Len[i]]) Len[i]++; 32 if(Len[i]+i>mx) 33 { 34 mx=Len[i]+i; 35 id=i; 36 sum=max(sum,Len[i]); 37 } 38 } 39 return (sum-1); 40 } 41 int main() 42 { 43 int t=0; 44 while(~scanf("%s",s)) 45 { 46 //memset(Len,0,sizeof(Len)); 47 if(strcmp("END",s)==0) break; 48 len=strlen(s); 49 init(); 50 printf("Case %d: %d\n",++t,manacher()); 51 } 52 return 0; 53 }
标签:reads lse rac lan could ret print 序列 find
原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11235706.html