博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最长回文子串之Manacher算法
阅读量:4620 次
发布时间:2019-06-09

本文共 1571 字,大约阅读时间需要 5 分钟。

以为例。

manacher算法:

设一个数组p,p[i]表示以第i个字符为中心的最大半径,最大的p[i]就是最长的回文子串了。

不过这样要用两个循环,时间复杂度是(n*n)。

1 int solve(){ 2     int len = strlen(str), ans = 0; 3     for(int i = 0; i < len; i ++){ 4         for(int j = 0; i-j>=0 && i+j < len; j++){ 5             if(str[i-j] != str[i+j])break; 6             if(j*2+1 > ans) ans=j*2+1; 7         } 8         for(int j = 0; i-j >= 0 && i+j+1 < len; j ++){ 9             if(str[i-j] != str[i+j+1])break;10             if(2*j+2 > ans) ans = 2*j+2;11         }12     }13     return ans;14 }

而manacher算法可以快速的求p[i],设i之前的最大值为p[id]+id,那么p[id]+id大于i时,p[i] = min(p[2*id-i],p[id]+id-i),否则p[i] = 1,具体的证明过程可以参考。

AC代码:

1 #include 
2 #include
3 #include
4 using namespace std; 5 const int MAX = 1e6+10; 6 char str[MAX<<1]; 7 int p[MAX<<1]; 8 int solve(){ 9 int ans = 0, id = 0, len = strlen(str);10 for(int i = len; i >= 0; i --){11 str[i+i+2] = str[i];12 str[i+i+1] = '#';13 }14 str[0] = '*';15 for(int i = 2; i<2*len+1; i ++){16 if(p[id] + id > i) p[i] = min(p[2*id-i],p[id]+id-i);17 else p[i] = 1;18 while(str[i-p[i]] == str[i+p[i]])++p[i];19 if(p[id] + id < p[i]+i) id = i;20 if(ans < p[i]) ans = p[i];21 }22 return ans-1;23 }24 int main(){25 int n;26 scanf("%d",&n);27 while(n--){28 scanf("%s",str);29 printf("%d\n",solve());30 memset(str,0,sizeof(str));31 memset(p,0,sizeof(p));32 }33 return 0;34 }

 

转载于:https://www.cnblogs.com/xingkongyihao/p/7127923.html

你可能感兴趣的文章
9.22作业3
查看>>
LeetCode Ones and Zeroes
查看>>
求余符号的用法
查看>>
C语言文件操作函数(ANSI)详解(一)
查看>>
sizeof的用法
查看>>
(转)断点续传下载文件[带进度条类似迅雷]
查看>>
linux 查看数据库和表
查看>>
autoLayout
查看>>
bzoj 1232 [Usaco2008Nov]安慰奶牛cheer
查看>>
Codeforces 908G New Year and Original Order 数位dp
查看>>
短信接口
查看>>
EF提示“序列化类型为XXX的对象时检测到循环引用”(转载)
查看>>
Java语言编程 - Java历史简介
查看>>
微服务架构 - 离线部署k8s平台并部署测试实例
查看>>
第五章 继承
查看>>
python设置windows桌面壁纸
查看>>
js的reduce方法,改变头等函数
查看>>
matlab绘图
查看>>
能匹配C语言注释的正则表达式
查看>>
CLR Via CSharp----------Delegate&Lambda
查看>>