最长回文字符串(Manacher算法)
来源:互联网 发布:java 发送邮件 图片 编辑:程序博客网 时间:2024/06/05 11:50
最长回文字符串
在字符串类的题目中,经常会有让求最长回文字符串的题目,比较快速的暴力方法是把每一个字符都当成中间字符
然后向两边拓展,看最远能拓展到多长
但是这样做,时间复杂度为n^2
很多题目中还是会超时,这样就要用到新算法了,这个算法可以把时间复杂度降为o(n)
先说一下这个算法的核心思想,看下面的算法都是围绕着核心思想写的
对于一个字符串,如果该字符串为回文字符串 如 abacaba
以C为中点的回文字符串的半径为4 以第一个b为中点的最长回文字符串半径长为2
第二个b由于和第一个b关于c点对称,都被以c为中点的最长回文字符串中
这样以第二个b为中点的最长回文字符串的长度也为2(肯定成立,可以多举例)
这样,我们就少计算几下
但是这样还有疑问
如果这个串是这样的怎么办:abacabac
那么以第二个b为中点的最长回文字符串半径长为3
不符合上面规律了???
不存在的!!!!
因为以c为中点的回文字符串没有完全包含了cabac这个串 只包括了 aba这个串,c在外面了
那如何办??
只有老老实实的自己手动匹配了,看一下能匹配的哪里,如果可以匹配,那么一直匹配下去
这样就有代码的核心思想了
下面简单说一下代码
用id表示匹配的最远位置的中间点
mx表示回文串最远可以匹配到的位置
如果当前匹配到第 i 个字符 先判断一下,i是不是小于mx
小于说明当前这个字符是在某个回文字符串中的,这个字符串的中点为id
那么可以用上面的思想,把对称的那个字符的值复制过来
如果当前字符不在回文串内,那就老老实实的以当前第i个字符为中点向两边匹配
如果 ....a.......ac 如果两个a关于某个id对称,而第一个a的半径为5 ,那么上面的方法算,第二个a的半径为5
但是!!不是这样的 观察一下这个串,第二a的半径最多为2了
因为后面根本就没有字符了(或者不在回文串里)
考虑到这种情况,我们也要算一下是否复制过来的数是否不符合实际
即取最小值!!!
下面上代码
#include<vector>#include<iostream>#include<stdio.h>#include<string.h>using namespace std;const int N=300010;int n, p[N];char s[N], str[N];void kp(){ int i; int mx = 0;//表示回文串最远匹配到的位置 int id;//表示当前匹配到最远位置时的中心在哪 for(i=n; str[i]!=0; i++) str[i] = 0; //没有这一句有问题。。就过不了ural1297,比如数据:ababa aba for(i=1; i<n; i++) { if( mx > i )//如果回文串的长度覆盖到了 p[i] = min( p[2*id-i], p[id]+id-i );//p[id]+id 其实也就是mx 2*id-i表示与i关于id的对称点 else p[i] = 1;// for(; str[i+p[i]] == str[i-p[i]]; p[i]++)// ; while(str[i+p[i]] == str[i-p[i]]) p[i]++; if( p[i] + i > mx )//如果发现可以更新的最远位置,那么更新最远位置 { mx = p[i] + i; id = i; } }}void init()//将串初始化{ int i, j, k; str[0] = '$'; str[1] = '#'; for(i=0; i<n; i++) { str[i*2+2] = s[i]; str[i*2+3] = '#'; } n = n*2+2; s[n] = 0;}int main(){ int i, ans; while(scanf("%s",s)!=EOF) { n = strlen(s); init(); kp(); ans = 0; for(i=0; i<n; i++) { printf("%d ",p[i]); if(p[i]>ans) { ans = p[i]; } } printf("\n"); printf("%d\n", ans-1); } return 0;}
阅读全文
0 0
- 最长回文字符串(manacher算法)
- 最长回文字符串(Manacher算法)
- 最长回文字符串(manacher算法)
- 最长回文字符串--manacher算法
- 最长回文字符串 manacher算法
- manacher算法(最长回文字符串)
- 最长回文字符串 manacher算法
- 最长回文(Manacher算法)
- 找字符串中最长回文(Manacher算法)
- 【字符串处理】最长回文子串笔记(Manacher算法)
- 【转载】最长回文字符串(manacher算法)
- java manacher算法计算最长回文字符串
- 最长回文字符串Manacher
- MANACHER最长回文算法
- hdoj 最长回文 3068 (字符串&manacher)
- 最长回文字符串(Manacher Algorithm)
- 最长回文(manacher算法)(fromHDU)
- 最长回文(后缀数组||Manacher算法)
- Spring Cloud各组件总结归纳
- UIActive
- 转载:将自己写的Python代码打包放到PyPI上
- Springmvc下载Excel案例(二)
- Android Material Design CoordinatorLayout使用
- 最长回文字符串(Manacher算法)
- LinkedHashMap的实现原理
- pandas分析NBA2017-2018赛季球员球队数据
- mybatis 映射 List<String>
- 实验二之顺序表
- Java Annotation认知(包括框架图、详细介绍、示例说明)
- 网页
- 指针与数组和字符串
- spark-submit提交集群命令