Manacher算法 , 实例 详解 . NYOJ 最长回文
51 Nod http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1089

Manacher 算法
定义数组 p[i]表示以i为中心的(包含i个这个字符)回文串半径长.
将字符串s从前扫到后,来计算p[i] , 则最大的p[i]就是最长回文串长度 ,
由于s是从前扫描到最后的,所以需要计算p[i]时一定计算好了 p[1]~~p[i-1]
假设现在扫描到了i+k这个位置,现在需要计算p[i+k]
定义maxlen是位置i+k位置前所有回文串中能延伸到的最有右端的位置 ,即maxlen=p[i]+i; // p[i]表示半径长 , i 表示目前最长的位置 , //这有两种情况 .
1 : i+k 这个位置不在前面的任何回文串中 , 即 i+k>maxlen , 则促使换p[i+k]=1 ; // 意思就是本身就是一个回文串 , 此时的长度的为 1 --> p[i+k]=1 ; 然后p[i+k]左右延伸,即while(s[i+k+p[i+k]]==s[i+k]-p[i+k]) ++p[i+k]; // 这样计算出来 p[i+k]的长度 .
2 : i+k 这个位置被前面以位置i为中心的回文串包含,即maxlen>i+k;这样的话p[i+k]就不是从1开始的 .
由于回文串的性质 , 可知i+k这个位置与关于 i 的i-k对称,所以p[i+k]分为一下三种情况得出 ,
// 黑色的是i的回文串范围,蓝色的是i-k的回文串范围.
然后就是三种情况了
第一种情况 : i-k 回文串有一部分在 i 的回文串之外 , 如上图蓝色左端在黑色右端之外 , 这种情况p[i+k]=p[i]-k; // 这时候就有人会有疑惑了 , p[i-k]那里的长度比你上面上的p[i]-k要长呀 ? 很正确虽然p[i-k]的长度长但是 p[i]的延伸最终在那里终止了 就说明 i+p[i]和i-p[i]是不相同的两个符号 , 所以p[i+k]的长度最多只是 , p[i]-k;
第二种情况 : i-k的回文串全部在p[i]之内 , 所以p[i+k]=p[i-k]那么这是的p[i+k]会不会更长呢 , 不可能 原因的话自己想想 .
第三种情况 : i-k的右端和i的右端重合 , 这时候 p[i+k]最小是p[i]-k ; 并且可能继续增加 .
// NYOJ 的答案
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<sstream>
#include<map>
#include<cctype>
#include<limits.h>
using namespace std;
char s[]; // s 是 模式串
int p[]; // 表示 以 i 为中心 情况下 最长的 长度
int main()
{
while(scanf("%s",s)!=EOF)
{
memset(p,,sizeof(p));
int len=strlen(s),id=,maxlen=; // 字符串长度 ,
for(int i=len;i>=;--i) // 插入 # 解决 , 长度为奇偶的问题 .
{ //插入'#'
s[i+i+]=s[i];
s[i+i+]='#';
} //插入了len+1个'#',最终的s长度是1~len+len+1即2*len+1,首尾s[0]和s[2*len+2]要插入不同的字符
s[]='*'; //s[0]='*',s[len+len+2]='\0',防止在while时p[i]越界
for(int i=;i<*len+;++i) // 完善好字符串之后 ,
{
if(p[id]+id>i)
p[i]=min(p[*id-i],p[id]+id-i); // 如果超过的话 , 右边(p[id]+id-i)的大 如果不超过的话 左边(p[2*id-i])的 大
else
p[i]=;
while(s[i-p[i]] == s[i+p[i]]) // 第 26 -- 29 , 32 33 都是为了 减小时间复杂度 来设置的 .
p[i]++;
if(id+p[id]<i+p[i]) // 这个 id+p[id] 是模式串中已经解决的 最右端 问题 .
id=i;
if(maxlen<p[i])
maxlen=p[i];
}
cout<<maxlen-<<endl;
}
return ;
}
Manacher算法 , 实例 详解 . NYOJ 最长回文的更多相关文章
- Manacher算法(马拉车)求最长回文子串
Manacher算法求最长回文字串 算法思路 按照惯例((・◇・)?),这里只是对算法的一些大体思路做一个描述,因为找到了相当好理解的博客可以参考(算法细节见参考文章). 一般而言,我们的判断回文算法 ...
- [hdu3068 最长回文]Manacher算法,O(N)求最长回文子串
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意:求一个字符串的最长回文子串 思路: 枚举子串的两个端点,根据回文串的定义来判断其是否是回文 ...
- javascript常用经典算法实例详解
javascript常用经典算法实例详解 这篇文章主要介绍了javascript常用算法,结合实例形式较为详细的分析总结了JavaScript中常见的各种排序算法以及堆.栈.链表等数据结构的相关实现与 ...
- 面试常用算法——Longest Palindromic Substring(最长回文子串)
第一种: public static void main(String[] args) { String s = "abcbaaaaabcdcba"; int n,m; Strin ...
- Web安全学习笔记之DES算法实例详解
转自http://www.hankcs.com/security/des-algorithm-illustrated.html 译自J. Orlin Grabbe的名作<DES Algorith ...
- HDU3068 最长回文 Manacher算法
Manacher算法是O(n)求最长回文子串的算法,其原理很多别的博客都有介绍,代码用的是clj模板里的,写的确实是异常的简洁,现在的我只能理解个大概,下面这个网址的介绍比较接近于这个模板,以后再好好 ...
- 领扣-5 最长回文子串 Longest Palindromic Substring MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Manacher算法:求解最长回文字符串,时间复杂度为O(N)
原文转载自:http://blog.csdn.net/yzl_rex/article/details/7908259 回文串定义:"回文串"是一个正读和反读都一样的字符串,比如&q ...
- Manarcher 求 字符串 的最长回文子串 【记录】
声明:这里仅仅写出了实现过程.想学习Manacher的能够看下这里给出的实现过程,算法涉及的一些原理推荐个博客. 给个链接 感觉讲的非常细 引子:给定一个字符串s,让你求出最长的回文子串的长度. 算法 ...
随机推荐
- 从Oracle迁移到Mysql之前必须知道的50件事
1. 对子查询的优化表现不佳. 2. 对复杂查询的处理较弱 3. 查询优化器不够成熟 4. 性能优化工具与度量信息不足 5. 审计功能相对较弱 6. 安全功能不成熟,甚至可以说很粗糙.没有用户组与角色 ...
- (04)odoo视图操作
-----------------更新时间19:04 2016-09-29 星期四11:17 2016-09-18 星期日18:13 2016-04-05 星期二15:05 2016-03-14 星期 ...
- hdu 3367(Pseudoforest ) (最大生成树)
Pseudoforest Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tot ...
- 重载Array类的contains方法
var allFilters = self.filtersContainer?.filters ?? [OpalFilter]() if let sorter = filtersContainer?. ...
- Python eclipse开发环境搭建
http://jingyan.baidu.com/article/cd4c2979101f02756f6e6064.html http://jingyan.baidu.com/article/1876 ...
- sql里Where条件顺序
以前的理解: sql语句里where后面的条件是否分先后顺序的 ,比如 A and B and C和 C and B and A 是一样,不像C语言 A && B 与B &&a ...
- easyui numberbox不可编辑
今天又遇到了给easyui中numberbox设置不可编辑的功能,在(http://www.jeasyuicn.com/api/docTtml/index.htm)API中找到了一个方法:
- Sharepoint2010突然之间不能打开页面,报503错误The service is unavailable
原因:安装Sahrepoint时的账号出现故障,可能是密码过期等等. 解决方案: 新建windows用户ada,密码设置为永不过期,隶属于:administrators/IIS-WPG/WSS-WPG ...
- HDU 1560 DNA sequence A* 难度:1
http://acm.hdu.edu.cn/showproblem.php?pid=1560 仔细读题(!),则可发现这道题要求的是一个最短的字符串,该字符串的不连续子序列中包含题目所给的所有字符串 ...
- 【第41套测试题NOIP2007】【排序】【DP】【高精度】【树】【图上路径】
先说点题外话,这两天的入学考试,炸了……语文有史以来最差,数学有史以来最差……还有4科,估计全炸……悲痛的心情,来调程序.这套题是8.31考的,从昨天晚上开始改的,因为第三题迟迟不想写,才拖到了现在. ...

