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算法求最长回文字串 算法思路 按照惯例((・◇・)?),这里只是对算法的一些大体思路做一个描述,因为找到了相当好理解的博客可以参考(算法细节见参考文章). 一般而言,我们的判断回文算法 ...
随机推荐
- 双十一只是在搞噱头么?看看ABBYY FineReader就知道了
双十一就这样轰轰烈烈的度过了,想问恢复正常工作日的你还好么,还能好好工作么,十分钟查一次物流的有木有? 由于ABBYY FineReader 12 限量200套半价活动过于火爆,各位小主也是用实际行动 ...
- 带你学C带你飞!
C语言免费课程推荐:带你学C带你飞! 想学习C语言,首先就要了解什么是C语言: C语言是一门通用计算机编程语言,应用广泛.C语言的设计目标是提供一种能以简易的方式编译.处理低级存储器.产生少量的机器码 ...
- 进程线程之pid,tid
Linux中,每个进程有一个pid,类型pid_t,由getpid()取得.Linux下的POSIX线程也有一个id,类型pthread_t,由pthread_self()取得,该id由线程维护,其i ...
- [luogu3195 HNOI2008] 玩具装箱TOY (斜率优化dp)
题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...
- 使用python备份指定目录并删除备份超过一定时长的文件
#!/usr/bin/env python #-*- coding: utf-8 -*- """ @Project:Py @author: @Email: @Softwa ...
- MySQL 面试题(一)
原文地址:http://www.2cto.com/database/201311/254385.html 作者:黄杉(红黑联盟) 公司招聘MySQL DBA面试心得 1 2年MySQL DBA经 ...
- %02x与%2x之间的区别
输出最小宽度用十进制整数来表示输出的最少位数.若实际位数多于定义的宽度,则按实际位数输出,若实际位数少于定义的宽度则补以空格或0(当最小宽度数值以0开头时). X 表示以十六进制形式输出02表示不足两 ...
- JavaScript 常见创建对象的方式
JavaScript 有哪几种创建对象的方式? javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON:但写法有很多种,也能混合使用. (1)对象字面量的方式 ...
- Java实现把两个数组合并为一个的方法总结
本文实例讲述了Java实现把两个数组合并为一个的方法.分享给大家供大家参考,具体如下: 在Java中,如何把两个String[]合并为一个? 看起来是一个很简单的问题.但是如何才能把代码写得高效简洁, ...
- 洛谷——P3398 仓鼠找sugar
https://www.luogu.org/problem/show?pid=3398#sub 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴 ...