manacher算法--最长回文子串
来源:互联网 发布:ubuntu查看64位 32位 编辑:程序博客网 时间:2024/06/11 15:59
问题概述:输入一个字符串,输出它的最长回文子串
输入样例: 对应输出:
abbaabcba 5
manacher算法步骤:
①处理字符串,使所有字母左右各有一个符号"#",且只有一个,第一个字符(str[0])设为"&"最后一个字符后面改'\0'
例如:abbaabcba处理后为&#a#b#b#a#a#b#c#b#a#'\0'
目的:将奇数/偶数长度的回文子串全部转换成奇数长度
②设一个数组P[i]来记录以字符Str[i]为中心的最长回文子串向左/右扩张的长度(回文字符串长度半径,最小为1),
其中P[0]=0
例如: & # a # b # b # a # a # b # c # b # a # \0
对应P[i]:0 1 2 1 2 5 2 1 2 5 2 1 2 1 6 1 2 1 2 1
③再增加两个辅助变量id和mx,其中id表示最大回文子串中心的位置,mx则为id+P[id]也就是最大回文子串的边界
④从第一个字符("#")开始循环,用while(str[i+p[i]]==str[i-p[i]]) p[i]++判断以i为中心回文半径,
当然如果mx>i,那么P[i]一定>=min(P[2*id-i], mx-i),直接初始化P[i]=min(P[2*id-i], mx-i)再循环以省时间
原理:http://blog.csdn.net/ggggiqnypgjg/article/details/6645824/
复杂度:O(n)
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int p[200010];char s[100010], str[200010];int main(void){int n, i, k, ans, mx, id;while(scanf("%s", s)!=EOF){n = strlen(s);memset(str, '\0', sizeof(str));str[0] = '$';str[1] = '#';for(i=0;i<=n-1;i++) /*步骤1*/{k = (i+1)*2;str[k] = s[i];str[k+1] = '#';}n = k+1;s[n+1] = 0;mx = ans = 0;for(i=1;i<=n;i++){p[i] = 1;if(mx>i)p[i] = min(p[2*id-i], mx-i+1);while(str[i+p[i]]==str[i-p[i]])p[i]++;if(p[i]+i-1>mx){mx = p[i]+i-1;id = i;}ans = max(ans, p[i]);}printf("%d\n", ans-1);}return 0;}
阅读全文
1 0
- Manacher算法求最长回文子串
- Manacher算法求最长回文子串
- 最长回文子串(Manacher算法)
- Manacher算法 最长回文子串
- 最长回文子串的manacher算法
- 最长回文子串,Manacher算法
- Poj3974 最长回文子串 Manacher算法
- 最长回文子串 manacher算法
- Manacher算法(最长子回文串)
- hihocoder1032(最长回文子串manacher算法)
- HDU3068(最长回文子串manacher算法)
- 最长回文子串 用manacher算法
- hiho1032 : 最长回文子串 Manacher算法
- 最长回文子串 - Manacher算法
- 最长回文子串Manacher算法
- Manacher算法 - 最长回文子串
- manacher算法-最长子回文串
- 最长回文子串-Manacher算法
- Handler机制分析(1)
- Android系统服务分析之服务注册过程
- 图像处理算法——卷积
- 5-13 Insert or Merge (25分)
- 【PAT】【Advanced Level】1006. Sign In and Sign Out (25)
- manacher算法--最长回文子串
- AVL平衡树(山东省选 郁闷的小J)
- 事件监听器 java.lang.NoClassDefFoundError
- day_04_内存管理
- hdu 2097 水题
- unity3d打包发布Apk流程
- 6/27作业:多态
- MO CALL流程
- 几种网络协议的定义及区别