转自:https://segmentfault.com/a/1190000008484167

/*

由于回文分为偶回文(比如 bccb)和奇回文(比如 bcacb),而在处理奇偶问题上会比较繁琐,所以这里我们使用一个技巧,在字符间插入一个字符(前提这个字符未出现在串里)。举个例子:s="abbahopxpo",转换为s_new="$#a#b#b#a#h#o#p#x#p#o#"(这里的字符 $ 只是为了防止越界,下面代码会有说明),如此,s 里起初有一个偶回文abba和一个奇回文opxpo,被转换为#a#b#b#a##o#p#x#p#o#,长度都转换成了奇数。
  定义一个辅助数组int p[]p[i]表示以s_new[i]为中心的最长回文的半径,例如:

i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
s_new[i] $ # a # b # b # a # h # o # p # x # p # o #
p[i]   1 2 1 4 5 2 1 2 1 2 1 2 1 2 1 6 1 2 1 2 1

可以看出,p[i]-1正好是原字符串中最长回文串的长度。
  Manacher算法之所以快,就快在对 p 数组的求法上有个捷径。在我们解决了奇偶回文的繁琐时,剩下的难点就是求 p 数组,按照普通思维,我们是这样求解的:求解p[i],先初始化p[i]=1,再以s_new[i]为中心判断两边是否相等,相等就p[i]++。这就是普通的思维,但是我们想想,能否让p[i]的初始化不是 1,让它更大点,看下图:

  设置两个变量,mx 和 id 。
  mx 代表以s_new[id]为中心的最长回文最右边界,也就是mx=id+p[id]
  假设我们现在求p[i],也就是以s_new[i]为中心的最长回文半径,如果i<mx,如上图,那么:

 if (i < mx)
p[i] = min(p[2 * id - i], mx - i);

2 * id -i其实就是等于 j ,p[j]表示以s_new[j]为中心的最长回文半径,见上图,因为 i 和 j 关于 id 对称,我们利用p[j]来加快查找。

*/

时间复杂度:O(n)

应用:

求最长回文串长度

求原串以每个字符为中心的奇数长度回文串的长度

代码如下:

//S用来放原串,CS用来放新串
char S[maxn],CS[maxn<<1];
int P[maxn];
int Init(){
int len=strlen(S);
CS[0]='$';
CS[1]='#';
int cnt=2;
for(int i=0;i<len;i++){
CS[cnt++]=S[i];
CS[cnt++]='#';
}
CS[cnt]='\0';
return cnt;
}
int Manacher(){
int len=Init();
int ans=-1;
int id,mx=0;
for(int i=1;i<len;i++){
if(i<mx) P[i]=min(P[2*id-i],mx-i);
else P[i]=1;
while(CS[i-P[i]]==CS[i+P[i]]) P[i]++;
if(mx<i+P[i]){
id=i;
mx=i+P[i];
}
ans=max(ans,P[i]-1);
}
return ans;
}

  

Manacher模板(O(n)内求最长回文串长度)的更多相关文章

  1. UVa 11404 回文子序列(LCS求最长回文串长度)

    https://vjudge.net/problem/UVA-11404 题意: 给定一个由小写字母组成的字符串,删除其中的0个或多个字符,使得剩下的字母(顺序不变)组成一个尽量长的回文串.如果有多解 ...

  2. 字符串的最长回文串:Manacher’s Algorithm

    题目链接:Longest Palindromic Substring 1. 问题描述 Given a string S, find the longest palindromic substring ...

  3. Manacher's Algorithm 马拉车算法(求最长回文串)

    作用:求一个字符串中的最长子串,同时还可以求所有子串的长度. 题目链接: https://vjudge.net/contest/254692#problem/B 最长回文串长度的代码: int Man ...

  4. (最长回文串 模板) 最长回文 -- hdu -- 3068

    http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory ...

  5. manacher 算法(最长回文串)

    manacher算法: 定义数组p[i]表示以i为中心的(包含i这个字符)回文串半径长 将字符串s从前扫到后for(int i=0;i<strlen(s);++i)来计算p[i],则最大的p[i ...

  6. Manacher(最长回文串)

    http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符 ...

  7. ACM题目————最长回文串

    Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等   Input 输入有多组cas ...

  8. Manacher算法 - 求最长回文串的利器

    求最长回文串的利器 - Manacher算法 Manacher主要是用来求某个字符串的最长回文子串. 不要被manacher这个名字吓倒了,其实manacher算法很简单,也很容易理解,程序短,时间复 ...

  9. HDU 3068 最长回文 (Manacher最长回文串)

    Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba, abba等   Input 输 ...

随机推荐

  1. 西里尔字 俄语 - Cyrillic

    https://zh.wikipedia.org/wiki/%E8%A5%BF%E9%87%8C%E5%B0%94%E5%AD%97%E6%AF%8D 其他编码[编辑] 其他适用西里尔字母的字符编码系 ...

  2. 绘图matplotlib

    前言 matplotlib是python的一个绘图库,如果你没有绘制过图,可以先试试js的绘图库http://www.runoob.com/highcharts/highcharts-line-lab ...

  3. Java高级应用(一)

    下面来介绍一下Java的高级应用有哪些. Java高级应用 第一讲 类加载 (一).类加载 类加载器是一个特殊的类,负责在运行时寻找和加载类文件.Java允许使用不同的类加载器,甚至是自定义类加载器. ...

  4. 【串线篇】idea下的springboot入门配置

    1.Spring Boot 简介 简化Spring应用开发的一个框架: 整个Spring技术栈的一个大整合: J2EE开发的一站式解决方案: 2.微服务 2014,martin fowler 微服务: ...

  5. table 中 当前行变量的获取

  6. vue 前后端分离 接口及result规范 及drf安装使用方法

    接口 # 接口:url链接,通过向链接发送不同的类型请求与参数得到相应的响应数据​# 1.在视图层书写处理请求的 视图函数# 2.在路由层为视图函数配置 url链接 => 产生接口# 3.前台通 ...

  7. 开源实践分享:Ceph bluestore部署实践

    https://blog.51cto.com/99cloud/2119884 Ceph bluestore部署 首先为大家分享Ceph bluestore具体该如何部署,使用环境如下• 单节点• Ce ...

  8. sed编辑器基础

    一. 更多的替换选项 ①替换标记 root@localhost sed]# cat data4.txt This is a test of the test script. This is the s ...

  9. MySQL图形化管理工具之Navicat安装以及激活

    软件以及激活包下载地址 1. 安装navicat 双击navicat_trial_11.1.20.0.1449226634.exe,一路下一步安装(记住安装目录) 2. 激活 双击PatchNavic ...

  10. SCP-bzoj-1085

    项目编号:bzoj-1085 项目等级:Safe 项目描述: 戳这里 特殊收容措施: A*(上下界剪枝). 答案上界:15. 答案下界:当前步数+当前状态剩余步数估价. 这里我们简单地设计估价函数为当 ...