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];}
}

转载于:https://www.cnblogs.com/Mrsrz/p/7308621.html

Manacher 求最长回文子串算法相关推荐

  1. Manacher马拉车算法求最长回文子串

    终于把马拉车算法搞明白了!赶紧记录一下. 这个算法用于查找一个字符串的最长回文子串 马拉车算法依次给数组p[i]赋值,马拉车算法的本质就是在每次给数组p[i] 赋值时尝试进行偷懒 例如,当要给p[6] ...

  2. 马拉车算法(manacher)求最长回文子串

    关于回文字符串的概念大家可以大致去搜索一下,这里不赘述. 一.解题思路 当前字符串 最长回文子串: 思路实际上很简单,就是遍历每一个元素,然后分别以这个元素为中心,向两边扩展,比如说现在i = 4,那 ...

  3. Manacher's algorithm: 最长回文子串算法

    Manacher 算法是时间.空间复杂度都为 O(n) 的解决 Longest palindromic substring(最长回文子串)的算法.回文串是中心对称的串,比如 'abcba'.'abcc ...

  4. python求回文_python实现求最长回文子串长度

    给定一个字符串,求它最长的回文子串长度,例如输入字符串'35534321',它的最长回文子串是'3553',所以返回4. 最容易想到的办法是枚举出所有的子串,然后一一判断是否为回文串,返回最长的回文子 ...

  5. 字符串处理 —— 回文串相关 —— 求最长回文子串

    [暴力枚举] 求最长回文串最容易的方法就是暴力枚举,求出字符串的每一个子串,然后判断是不是回文,找到最长的那个回文串 求每一个子串的时间复杂度为 O(N^2),判断一个子串是不是回文时间复杂度为 O( ...

  6. C语言实现:最长回文子串算法

    1.问题描述: 给定一个字符串,求它的最长回文子串的长度. 回文定义:字符串的逆序和其本身一致.(例如:abcba) 2.两种解法: 2.1.中心扩散法: 思路: 验证回文是从字符串两端开始对比,算法 ...

  7. mannachar(马拉车)求最长回文子串

    mannachar(马拉车)究竟是什么东西呢? 很简单,就是能让你在O(n)的复杂度内求出一个串的最长回文子串.传统的算法复杂度是O(n^2),呐,为什么mannachar能变快呢?因为mannach ...

  8. 【HDU - 3068】最长回文(Manacher算法,马拉车算法求最长回文子串)

    题干: 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.  回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有多组case,不超过120组 ...

  9. (力扣)中心扩散法求最长回文子串

    Question: 给定一个字符串,输出其中最长的回文子串. 几种解法: 暴力枚举:时间复杂度:O(n3)(略) (双层枚举:O(n2)判断是否为回文串:O(n)) 动态规划:时间复杂度O(n2),空 ...

最新文章

  1. python界面图片-python图形用户界面(六):可视化给图片添加上文字
  2. c# 串口最简单接收十六进制
  3. 一个计算机高手的成长历程[转]
  4. web系统架构设计中需要知道的点(前端篇)
  5. 冒泡排序 自带时间复杂度测试
  6. linux 模拟时序,stm32GPIO模拟时序读写nandflash(K9F1G08U0B)问题
  7. mysql数据库索引页号为什么从3开始_MySQL数据库快问快答
  8. json 语法_JSON的基本语法
  9. Unity上的Oculus Quest2开发(1) ——首先要空工程能在Quest上跑起来吧
  10. Python创建cvs文件,包含标签和图片数据
  11. [总]Android高级进阶之路
  12. python项目---数据可视化(02)
  13. windows XP小技巧
  14. java 安卓 物联网_面向物联网的Android应用开发与实践
  15. java经典算法50题_JAVA经典算法50题
  16. 【STM32H7】第30章 ThreadX GUIX炫酷实用的时钟表盘设计,结合硬件RTC实时时钟
  17. Excel简单使用宏
  18. Windows简单TCPIP服务
  19. 为什么在wps中调整了0.5倍行距,某一页的行数不会发生变化?
  20. logoff user in window 2008

热门文章

  1. 远程管理客户端--SCCM
  2. mysql学习总结一:mysql的安装,介绍,基本命令操作
  3. zookeeper系列(二)实战master选举
  4. idea 中使用@Autowired注入mybatis Mapper接口时报错
  5. Ruby已死——必须关注的内存问题
  6. IBATIS + ORACLE(二)
  7. CSS_伪元素_伪类
  8. winform 窗口 属性
  9. Java 异常基础 Exception
  10. 白血病孕妇产子继母子双双安然