Manacher算法(马拉车)求最长回文子串
Manacher算法求最长回文字串
算法思路
按照惯例((・◇・)?),这里只是对算法的一些大体思路做一个描述,因为找到了相当好理解的博客可以参考(算法细节见参考文章)。
一般而言,我们的判断回文算法的思想是从一个点开始向两边拓展直到无法拓展为止,这个时候就得到了回文串的长度,但这个算法的时间复杂度是\(O(n^2)\)的。在这个算法进行的过程中,我们有可能会不断地拓展了重复的位置而产生重复计算,升高了时间复杂度。马拉车算法通过充分利用已经遍历过的信息,尽量不会重复去遍历已知信息的区段,而且利用一定的空间来记录信息,是一种空间换时间的做法。所谓利用信息,实际上是利用回文串本身的性质,具体的,是一个回文串包含回文字串时的关于对称轴对称的性质。分情况进行了不同处理。
同时,为了避免代码的重复冗余,在原回文串中加入了'#','$'等字符,使奇偶统一讨论,而且能够较为方便的找回对应于原串的信息。
代码
#include <iostream>
#include <cstring>
#define max_n 1005
using namespace std;
int p[max_n];//p[i]表示以i为中心的最长回文的半径
char s[max_n];//记录原串
char t[max_n];//经处理的串
int center = -1;//记录最长回文子串在原串中的起始位置
int max_len = -1;//记录最长回文字串的长度
int Init()//处理原串
{
int len = strlen(s);
t[0] = '$';
t[1] = '#';
int j = 2;
for(int i = 0;i<len;i++)
{
t[j++] = s[i];
t[j++] = '#';
}
t[j] = '\0';
return j;
}
int manacher()
{
int len = Init();
int id;//当前回文子串中心
int mx = 0;//当前回文子串右端点(不包含)
for(int i = 0;i<len;i++)
{
if(i<mx)
{
p[i] = min(p[2*id-i],mx-i);//包含了两种情况
}
else
{
p[i] = 1;//一种情况
}
while(t[i+p[i]]==t[i-p[i]])
{
p[i]++;//看是否还可拓展
}
if(mx<i+p[i])//更新回文子串中心和右端
{
id = i;
mx = i+p[i];
}
if(max_len<p[i]-1)
{
max_len = p[i]-1;//更新最长回文子串长度
center = (i-p[i])/2;//及起始点
}
}
return max_len;
}
int main()
{
cin >> s;
cout << manacher() << endl;
for(int i = center;i<max_len;i++)
{
cout << s[i];
}
cout << endl;
return 0;
}
实例
这里给一个实例:
abbaho
转化后为:$#a#b#b#a#h#o#,可尝试照着代码分析一下,看看mx和id是怎么变化的,对应情况又是怎么处理的
处理串和原串的对应关系
这里说一下处理后的串的信息怎么和原来的串对应上。
这里就要举栗子啦。
原串是abbaho,处理后$#a#b#b#a#h#o#,看中间的#的位置5,p[5]=5,此时原串的回文长度是4,发现4=p[5]-1;起始位置是0,发现(5-p[5])/2=0
再来看看anppnb,处理后为$#a#n#p#p#n#b#,中间#的位置是7,p[7]=5,此时原串回文长度是4,发现4=p[7]-1;起始位置是1,发现(7-p[7])/2=1
于是不完全归纳出:
原串回文长度=p[处理串的回文中心位置]-1
原串回文起始位置=(处理串回文中心位置-p[处理串回文中心位置])/2
参考文章
原串处理串对应关系请见:
Grandyang,Manacher's Algorithm 马拉车算法,https://www.cnblogs.com/grandyang/p/4475985.html
算法流程讲解请见:
BIT祝威 ,[译+改]最长回文子串(Longest Palindromic Substring) Part II,https://www.cnblogs.com/bitzhuwei/p/Longest-Palindromic-Substring-Part-II.html
具体的算法分析请见:
刘毅,Manacher 算法 ,https://subetter.com/algorithm/manacher-algorithm.html
Manacher算法(马拉车)求最长回文子串的更多相关文章
- manacher算法_求最长回文子串长度
很好的总结,转自: http://blog.csdn.net/dyx404514/article/details/42061017 总结为:两大情况,三小情况. 两大情况:I. i <= p 1 ...
- manacher算法学习(求最长回文子串长度)
Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...
- Manacher模板( 线性求最长回文子串 )
模板 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> us ...
- Manacher算法讲解——字符串最长回文子串
引 入 引入 引入 Manachar算法主要是处理字符串中关于回文串的问题的,这没什么好说的. M a n a c h e r 算 法 Manacher算法 Manacher算法 朴素 求一个字符串中 ...
- 【Manacher算法】求最长回文串的优秀算法
先贴一下代码~ //by 减维 #include<cstdio> #include<iostream> #include<cstring> #include< ...
- [hdu 3068] Manacher算法O(n)最长回文子串
一个不错的讲解:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/01.05.md # ...
- Manacher算法:求解最长回文字符串,时间复杂度为O(N)
原文转载自:http://blog.csdn.net/yzl_rex/article/details/7908259 回文串定义:"回文串"是一个正读和反读都一样的字符串,比如&q ...
- hihoCoder #1032 : 最长回文子串 [ Manacher算法--O(n)回文子串算法 ]
传送门 #1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相 ...
- 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 ...
随机推荐
- web服务器获取请求客户端真实地址的方法
服务器获取客户端或者网页的请求,获取IP时需要注意,因为一个请求到达服务器之前,一般都会经过一层或者多层代理服务器,比如反向代理服务器将http://192.168.1.10:port/ 的URL反向 ...
- ASP.NET CoreMVC 中的控制器
Controller in ASP.NET Core MVC 在本节中,我们将讨论 Controller 是什么以及它在 ASP.NET Core MVC 中的作用. Fiddler 需要大家提前装一 ...
- [LeetCode] 416. Partition Equal Subset Sum 相同子集和分割
Given a non-empty array containing only positive integers, find if the array can be partitioned into ...
- (转)yum只下载不安装软件包
方法一:使用yum的downloadonly插件 步骤: (1) 先安装downloadonly插件 yum install yum-plugin-downloadonly (2)使用–downlo ...
- 消息队列:RabbitMQ安装
1. 安装RabbitMQ之前需要先安装Erlang环境 然后配置环境变量 2. 安装完后 我们进入到我们安装到 sbin目录C:\Program Files\RabbitMQ Server\rabb ...
- C语言I作业12—学期总结
一.我学到的内容 二我的收获 作业 收获 C语言博客作业1 刚开始初步了解C语言方面的知识 学会Markdown基本语法 C语言博客作业2 学会了应该如何提问 PTA系统常见问题解答 学会了MinGW ...
- 【洛谷】P4594 [COCI2011-2012#5] BLOKOVI
本来已经有一个专门记录洛谷题目的博客了,但这个题之毒瘤...... 为你专门写一篇总行了吧...... 传送门 先说一句,这个题每次摆放都靠到最右边不一定是最优的 因为它可以这个亚子 就是说上面那个块 ...
- 谈谈IntersectionObserver懒加载
概念 IntersectionObserver接口(从属于Intersection Observer API)为开发者提供了一种可以异步监听目标元素与其祖先或视窗(viewport)交叉状态的手段.祖 ...
- Spring事物隔离级别及事物传播行为@Transactional实现
阅读本篇文章前,请先阅读如下文章: 四种事物隔离级别详解 先看下@Transactional可以配制那些参数及以其所代表的意义. isolation 枚举org.springframework.tra ...
- intelliJ 社区版-找不到 plugins选项
丢人了... 今天 在intelliJ社区版上面找不到 plugins 选项了, 其实是有的,我看的是项目的 settings 当然没有了, (1)如果直接点击File==> 这样就是没有plu ...