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算法(马拉车)求最长回文子串的更多相关文章

  1. manacher算法_求最长回文子串长度

    很好的总结,转自: http://blog.csdn.net/dyx404514/article/details/42061017 总结为:两大情况,三小情况. 两大情况:I. i <= p 1 ...

  2. manacher算法学习(求最长回文子串长度)

    Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...

  3. Manacher模板( 线性求最长回文子串 )

    模板 #include<stdio.h> #include<string.h> #include<algorithm> #include<map> us ...

  4. Manacher算法讲解——字符串最长回文子串

    引 入 引入 引入 Manachar算法主要是处理字符串中关于回文串的问题的,这没什么好说的. M a n a c h e r 算 法 Manacher算法 Manacher算法 朴素 求一个字符串中 ...

  5. 【Manacher算法】求最长回文串的优秀算法

    先贴一下代码~ //by 减维 #include<cstdio> #include<iostream> #include<cstring> #include< ...

  6. [hdu 3068] Manacher算法O(n)最长回文子串

    一个不错的讲解:https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/01.05.md # ...

  7. Manacher算法:求解最长回文字符串,时间复杂度为O(N)

    原文转载自:http://blog.csdn.net/yzl_rex/article/details/7908259 回文串定义:"回文串"是一个正读和反读都一样的字符串,比如&q ...

  8. hihoCoder #1032 : 最长回文子串 [ Manacher算法--O(n)回文子串算法 ]

    传送门 #1032 : 最长回文子串 时间限制:1000ms 单点时限:1000ms 内存限制:64MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相 ...

  9. PAT甲题题解-1040. Longest Symmetric String (25)-求最长回文子串

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789177.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  10. hdu 3068 最长回文(manachar求最长回文子串)

    题目连接:hdu 3068 最长回文 解题思路:通过manachar算法求最长回文子串,如果用遍历的话绝对超时. #include <stdio.h> #include <strin ...

随机推荐

  1. [LeetCode] 375. Guess Number Higher or Lower II 猜数字大小之二

    We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You have to gues ...

  2. GreenPlum 大数据平台--集群恢复

    一,问题描述 :::: gpinitstandby:greenplum01:gpadmin-[ERROR]:-Cannot use -n option when standby master has ...

  3. 2条最佳实践App疯狂增长逻辑

    2条最佳实践App疯狂增长逻辑 1.不断打造和强化产品的不可或缺属性 产品的核心价值是什么?对你的客户来言,为什么是你? 2.等待“阿哈时刻” 进入快速推广 用户使用产品眼前一亮的时刻,是用户真正发现 ...

  4. Oracle常用函数集锦

    1.wmsys.wm_concat函数 将列转为行.例子: --表里的数据如下 SQL> select * from idtable; ID NAME ---------- ---------- ...

  5. fiddler抓包-5-Composer功能进行接口测试

    前言 fiddler是个强大的抓接口工具,轻松看出接口的所有参数,这里介绍一个Composer功能它也可以进行接口测试,平时接口可能传参错误,我们可以拖拽接口来改参数直接再请求了,非常方便! 一.Co ...

  6. Reimage Isilon cluster,结果忘记了修改管理口的netmask,怎么办?

    网页打不开了,正常的SSH也连不上,只能用串口,连接到节点上. 然后使用运行下面的命令来修改netmask: isi network subnets modify groupnet0.subnet0 ...

  7. tomcat闪退的解决思路

    用Tomcat总会遇到启动Tomcat闪退的问题. 什么叫闪退啊,就是闪一下,就退出了控制台. 都闪退了,为啥闪退也不知道呀,又没有错误信息,所以就要先阻止闪退,先看到错误信息,知道启动不起来的原因. ...

  8. Ubuntu19 安装 pylearn2

    环境: /etc/issue # Ubuntu 19.10 \n \l python -V # Python 其中,python环境是我自己建立的虚拟 venv 方便测试( 相当于你的python 实 ...

  9. 只安装自己需要的 Office 2016 组件的方法

    以往Office的安装包都采用的是MSI安装器,允许用户在安装时选择安装的组件,但是微软发布的Office 2016安装包只提供了C2R(ClickToRun)方式,因此默认情况下用户无法选择安装组件 ...

  10. Spring+Mybatis动态切换数据源

    功能需求是公司要做一个大的运营平台: 1.运营平台有自身的数据库,维护用户.角色.菜单.部分以及权限等基本功能. 2.运营平台还需要提供其他不同服务(服务A,服务B)的后台运营,服务A.服务B的数据库 ...