Manacher 求最长回文子串算法
Manacher算法,是由一个叫Manacher的人在1975年发明的,可以在$O(n)$的时间复杂度里求出一个字符串中的最长回文子串。
例如这两个回文串“level”、“noon”,Manacher算法先对其进行一个处理:
level --> #l#e#v#e#l#
noon --> #n#o#o#n#
这样的好处就是,不论回文子串的长度是奇是偶,最后求出的回文子串长度都是奇数的,就不用分类讨论了。
我们用p[i]表示以i为中心的最长回文子串向两边扩展的长度,例如:
s # 1 # 2 # 2 # 1 # 2 # 3 # 2 # 1 #
p 1 2 1 2 5 2 1 4 1 2 1 6 1 2 1 2 1
我们发现,p[i]-1刚好为原串以i位置为中心的最长回文子串长度。
在Manacher算法中,需要两个辅助变量。id为当前最长回文子串的中心,mx为以id为中心的最长回文子串的右边界(id+p[id])。这个算法的核心部分在这里:
if(mx>i)p[i]=min(p[(id<<1)-i],mx-i);else p[i]=1;
当 mx - i > p[j] 的时候,以s[j]为中心的回文子串包含在以s[id]为中心的回文子串中,由于 i 和 j 对称,以S[i]为中心的回文子串必然包含在以S[id]为中心的回文子串中,所以必有 p[i] = p[j]。
当 p[j] > mx - i 的时候,以s[j]为中心的回文子串不完全包含于以s[id]为中心的回文子串中,但是由于对称性,以s[i]为中心的回文子串,其向右至少会扩张到mx的位置,也就是说 p[i] >= mx - i。至于mx之后的部分是否对称,就只能一个一个匹配了。
当 mx < i 的时候,我们就无法对 p[i] 进行更多的推算,只能一个一个匹配。

上图给出了Manacher的详解和线性复杂度的证明。
以下是核心代码:
C++ Code:
void manacher(){
int mx=0,id=0;
for(i=1;i<=n;++i){
if(mx>i)p[i]=min(p[(id<<1)-i],mx-i);else p[i]=1;
while(s[i-p[i]]==s[i+p[i]])++p[i];
if(i+p[i]>mx)mx=i+p[id=i];
}
}
Manacher 求最长回文子串算法的更多相关文章
- manacher求最长回文子串算法
原文:http://www.felix021.com/blog/read.php?2040 首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个 ...
- manacher求最长回文子串算法模板
#include <iostream> #include <cstring> #include <cstdlib> #include <stdio.h> ...
- hdu 3068 最长回文 【Manacher求最长回文子串,模板题】
欢迎关注__Xiong的博客: http://blog.csdn.net/acmore_xiong?viewmode=list 最长回文 ...
- Manacher模板( 线性求最长回文子串 )
模板 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> us ...
- PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- hdu 3068 最长回文(manachar求最长回文子串)
题目连接:hdu 3068 最长回文 解题思路:通过manachar算法求最长回文子串,如果用遍历的话绝对超时. #include <stdio.h> #include <strin ...
- Manacher算法——求最长回文子串
首先,得先了解什么是回文串.回文串就是正反读起来就是一样的,如“abcdcba”.我们要是直接采用暴力方法来查找最长回文子串,时间复杂度为O(n^3),好一点的方法是枚举每一个字符,比较较它左右距离相 ...
- manacher算法求最长回文子串
一:背景 给定一个字符串,求出其最长回文子串.例如: s="abcd",最长回文长度为 1: s="ababa",最长回文长度为 5: s="abcc ...
- Manacher算法(马拉车)求最长回文子串
Manacher算法求最长回文字串 算法思路 按照惯例((・◇・)?),这里只是对算法的一些大体思路做一个描述,因为找到了相当好理解的博客可以参考(算法细节见参考文章). 一般而言,我们的判断回文算法 ...
随机推荐
- 算法23-------岛屿的最大面积 LeetCode 695
一.题目: 给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合.你可以假设二维矩阵的四个边缘都被水包围着. 找到给定 ...
- 算法22-----托普利茨矩阵leetcode766
1.题目 如果一个矩阵的每一方向由左上到右下的对角线上具有相同元素,那么这个矩阵是托普利茨矩阵. 给定一个 M x N 的矩阵,当且仅当它是托普利茨矩阵时返回 True. 示例 1: 输入: matr ...
- bootstrap fileinput控件 + django后台上传、回显简单使用
一.控件下载:https://github.com/kartik-v/bootstrap-fileinput/ 官网:http://plugins.krajee.com/file-input 需要引入 ...
- php 密码hash加密
做密码加密,记录一下. password_hash 函数在 PHP 5.5 时被引入. 此函数现在使用的是目前 PHP 所支持的最强大的加密算法 BCrypt .例子: $passwordHash = ...
- [Atcoder Code Festival 2017 Qual B Problem F]Largest Smallest Cyclic Shift
题目大意:给你\(A\)个a,\(B\)个b,\(C\)个c,要你构造一个字符串,使它的最小循环表示法最大.求这个表示法.解题思路:不知道怎么证,但把a.b.c当做单独的字符串扔进容器,每次把字典序最 ...
- qt quick中qml编程语言
Qt QML 入门 — 使用C++定义QML类型 发表于 2013 年 3 月 11 日 注册C++类 注册可实例化的类型 注册不实例化的QML类型 附带属性 注册C++类 注册可实例化的类型 如 ...
- 2019-03-18 OpenCV Tesseract-OCR 下载 安装 配置(cv2 报错)
OpenCV 下载 安装 配置 1.下载和Python版本对应的版本,此为下载地址 2.安装(在powershell管理员模式下安装) pip3 install .\opencv_python-3.4 ...
- H5新增的标签总结
1:便于排版的Form表单 HTML5为了方便排版,可以使form的表单标签脱离form的嵌套. 方法:form指定id,所有的标签标签都添加form= id属性. 例如: <form acti ...
- CODEVS——T 1269 匈牙利游戏 2012年CCC加拿大高中生信息学奥赛
http://codevs.cn/problem/1269/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Descript ...
- 深入理解Dalvik虚拟机- 解释器的执行机制
Dalvik的指令运行是解释器+JIT的方式,解释器就是虚拟机来对Javac编译出来的字节码,做译码.运行,而不是转化成CPU的指令集.由CPU来做译码,运行.可想而知.解释器的效率是相对较低的,所以 ...