最长回文子串(Manacher算法)
回文字符串,想必大家不会不熟悉吧?
回文串会求的吧?暴力一遍O(n^2)很简单,但当字符长度很长时便会TLE,简单,hash+二分搞定,其复杂度约为O(nlogn), 而Manacher算法能够在线性的时间内处理出最长回文子串。
让我们来看道题:http://acm.hdu.edu.cn/showproblem.php?pid=3068

这个算法的巧妙之处,便是把奇数的回文串和偶数的回文串统一起来考虑了。这一点一直是在做回文串问题中时比较烦的地方。这个算法还有一个很好的地方就是充分利用了字符匹配的特殊性,避免了大量不必要的重复匹配。那怎么去实现呢?
我们要求字符串s中最长的回文子串
Manacher重新构造了一个新数组,在每两个字符中间插入一个'#',如下图:

我们很容易发现,如果出现这种情况(如下图)在处理第三个字符('#')市,会发现扫到左侧时候可能会出现越界

为了避免索引数超出数组边界值做字符比较,可以在处理过的字符串的第一个位置(索引为0的位置)加入一个区分字符,笔者喜欢用'@'。

上图便是处理过的样子。(编号表示数组位数,3表示是s[3]的字符)
我们现在用p[i]数组表示以字符s[i]为中心的回文半径(如p[3] = 1)。
我们很容易发现最长子序列的长度刚好是(p[i] - 1)。
那么我们怎么来求p[i]数组呢?
步骤如下:
当处理到[i]的时候,我们去找0-i中是否存在一个数(设为id)使得p[id] + id > i,设mx = p[id] + id。

如上图,由于红的字符串是回文字符串,所以关于j对称的回文子串和关于i对称的回文子串是完全一样的(图中两段绿色的线条),而满足mx-i>P[j]时说明此时j的回文子串半径小于j到mx关于j对称的左端点的差,此时可以初始化P[i]=P[j]。但如果绿色部分超出id的回文串呢?
如下图:

紫色表示以j为中心的回文串超出以id为中心的回文半径的部分(即图中红色部分)由于红的字符串是回文字符串,所以关于j对称的回文子串和关于i对称的在mx和mx的对称点之间的回文子串是完全一样的(图中两段绿色的线条),而满足mx-i<=P[j]时说明此时j的回文子串半径大于或等于j到mx关于j对称的左端点的差,此时可以初始化P[i]=mx-i,超出部分只能一个个判断。再对P[i]的回文子串半径进行进一步的增大。(以上两图均取自参考论文)
综上所述初始化p[i] = min(p[j], mx - i);
对于超出回文字符串部分(即红色部分,我们只能一个一个的去判断)
即while(s[i + p[i]] == s[i - p[i]])p[i] += 1;
当mx <= i 的时候我们只能将p[i] 初始化为1(对于它都是未知的,只能通过一位一位去比较)。
附上总代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = + ; char s[N]; int p[N]; int n, id, mx; void work(){
id = mx = ;
int ans = ;
n = strlen(s);
for(int i = n; i >= ; i --){
s[ * i + ] = s[i];
s[ * i + ] = '#';
}
s[] = '@';
p[] = ;
for(int i = ; i < * n + ; i ++){
if(mx > i)p[i] = min(p[ * id - i], mx - i);
else p[i] = ;
while(s[i + p[i]] == s[i - p[i]]) p[i] += ;
if(mx < p[i] + i){
id = i;
mx = p[i] + i;
}
ans = max(ans, p[i] - );
}
printf("%d\n", ans);
} int main(){
while(scanf("%s", s) == )work();
return ;
}
参考资料:http://blog.csdn.net/pi9nc/article/details/9251455
最长回文子串(Manacher算法)的更多相关文章
- 九度OJ 1528 最长回文子串 -- Manacher算法
题目地址:http://ac.jobdu.com/problem.php?pid=1528 题目描述: 回文串就是一个正读和反读都一样的字符串,比如"level"或者"n ...
- lintcode最长回文子串(Manacher算法)
题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...
- 最长回文子串—Manacher 算法 及 python实现
最长回文子串问题:给定一个字符串,求它的最长回文子串长度.如果一个字符串正着读和反着读是一样的,那它就是回文串. 给定一个字符串,求它最长的回文子串长度,例如输入字符串'35534321',它的最 ...
- hihocoder #1032 : 最长回文子串 Manacher算法
题目链接: https://hihocoder.com/problemset/problem/1032?sid=868170 最长回文子串 时间限制:1000ms内存限制:64MB 问题描述 小Hi和 ...
- 5. Longest Palindromic Substring(最长回文子串 manacher 算法/ DP动态规划)
Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...
- HiHo 1032 最长回文子串 (Manacher算法求解)
/** * 求解最长回文字串,Manacher算法o(n)求解最长回文子串问题 **/ #include<cstdio> #include<cstdlib> #include& ...
- hihoCoder #1032 : 最长回文子串 [ Manacher算法--O(n)回文子串算法 ]
传送门 #1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相 ...
- 51nod1089 最长回文子串 manacher算法
0. 问题定义 最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字符串正着读和反着读是一样的,那它就是回文串.下面是一些回文串的实例: 12321 a aba abba aaaa ...
- 最长回文子串Manacher算法模板
Manacher算法能够在O(N)的时间复杂度内得到一个字符串以任意位置为中心的回文子串.其算法的基本原理就是利用已知回文串的左半部分来推导右半部分. 首先,在字符串s中,用rad[i]表示第i个字符 ...
- 求最长回文子串——Manacher算法
回文串包括奇数长的和偶数长的,一般求的时候都要分情况讨论,这个算法做了个简单的处理把奇偶情况统一了.算法的基本思路是这样的,把原串每个字符中间用一个串中没出现过的字符分隔开来(统一奇偶),用一个数组p ...
随机推荐
- MySql分类
基础 数据类型宽度 查看字段长度 数据类型 运算符 函数 查询 插入 更新 删除 索引 自定义存储过程和函数 视图 触发器 权限管理 备份和恢复 日志 优化 复制
- Python Memcached Script
介绍 利用 python 书写了 memcached 的启动等一类操作 尽量的实现脚本的复用性,以及脚本的可扩展性,已达到一劳永逸的效果, 并且添加了 memcached 监控搭建 memcached ...
- javascript 动态改变onclick事件
第一种:button.onclick = Function("alert('hello');"); 第二种:button.onclick = function(){alert(&q ...
- [转帖]迅为4412开发板最小linux系统的存储空间修改
本文转自迅为论坛:http://www.topeetboard.com 最小linux系统的存储空间修改以修改成 1G 存储空间为例来修改,如果需要改成其他大小的存储空间,参照此方法修改即可. 首先连 ...
- css shorthand属性简写
一.什么是shorthand 属性简写(shorthand)就是一次性声明一组相关的属性.好处呢当然是众所周知的,让css从臃肿无序升级为简洁有效具有高可读性. 大多数的人都使用属性简写,我也用,但是 ...
- Hadoop中WritableComparable 和 comparator
1.WritableComparable 查看HadoopAPI,如图所示: WritableComparable继承自Writable和java.lang.Comparable接口,是一个Writa ...
- 杂谈SharpDx中的WIC组件——我们需要WIC的图片编码功能么?
在前文 SharpDX之Direct2D教程II——加载位图文件和保存位图文件 中,发现在VB2010中不能很好的运用SharpDx中的WIC组件进行图片的编码工作.可能是我的设置问题,也可能是Sha ...
- 【OpenCV】全景拼接
从OpenCV3.0正式版开始,features2d中的一些接口,搬到附加库xfeatures2d中了,其中就有SIFT.SURF的特征检测方法,但是正常下载安装OpenCV并不包含附加库,因为附加库 ...
- LeetCode题解-----Majority Element II 摩尔投票法
题目描述: Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The a ...
- 怎样快速免费获取Windows版本的ZBrush
ZBrush是一款专业的3D绘制软件及数字雕刻软件,随着3D技术的不断进步,ZBrush也是越来越受到业内欢迎,在世界拥有了众多的粉丝和爱好者.相信很多用户对软件的体验就是从使用的版本开始的,本文就教 ...