manacher算法是一种可以在O(N)时间复杂度下求字符串所有回文子串的算法,也是求最大回文子串最高效的算法。这种算法在进行遍历的时候,充分利用了回文串的特性,减少了许多不必要的计算,使得时间复杂度降低到了线性水平。该算法的难度在于理解,一旦理解后,代码是非常简单的。

manacher算法有如下几个要点:

  • 如何计算回文串长度(O(N2N^2N2)算法)
  • 如何将奇回文串与偶回文串统一判断
  • 如何优化O(N2N^2N2)时间复杂度的中心拓展算法
    下面我们来一一讲解

一、如何计算回文串长度

如果没有时间上的限制,我们可以使用暴力的做法:中心拓展法

我们知道,如果一个字符串是回文串,那么该字符串必是中心对称的。故我们可以选择一个中心,从它开始,向两边逐一判断字符是否相同,拓展回文串长度。由于回文串可以是奇回文串也可以是偶回文串,我们需要选择一个字符或者选择两个字符中间作为中心进行逐一判断,故一共有 N + N - 1个中心。

二、奇回文串与偶回文串的统一判断

回文串既可以有aba的形式,也可以有abba的形式,在实际写代码的时候如果不进行处理,会使得代码变得比较复杂。
因此我们可以在每两个字符间及字符串头、尾加上一个不曾在字符串中出现过的字符,如#、$等字符,使得在进行遍历的时候可以不用分情况讨论

例如:

则我们可以对所有字符做中心拓展,得回文半径Pi,则原字符串的子回文串长度为Pi - 1
代码如下:

void mid(string s){int P[105];for(int i = 0;i<s.size();i++){P[i] = 1;while(s[i+P[i]]==s[i-P[i]]) P[i]++;     //P[i]为回文半径,故i±P[i]为需要进行拓展的最外层}
}

三、中心拓展算法的优化:manacher算法

目前我们已经有了时间复杂度为O(N2N^2N2)的算法,如何优化呢。

不难发现,回文串的特点为中心对称,也就是说在回文串当中,围绕对称中心,左半边与右半边是完全相同的。故一个在左半边回文串内的子回文串,也必定存在于右半边,如该字符串
以b为对称中心,左边aba的子回文串在右边也出现了,那么我们可以思考一下,如果以从左到右的顺序进行中心拓展遍历,是不是可以通过已经计算过的回文半径来给当前还未计算的回文半径进行赋值?答案是显然的,但我们还需要考虑几种不同的情况。

我们知道上述理论成立的基础,是建立在回文串左右对称的前提下的,也就是说,我们如果想把过去计算过的回文半径拿来用,必然需要判断一下子回文串是否包含在大回文串之内,也就是如下三种情况:

1、当前中心在回文串的对称位置下的子回文串在回文串内

这是最简单的情况也是我们最希望看到的情况,因为我们可以直接使用已经计算过的回文半径来进行赋值

如我们遍历到当前位置时(绿色箭头),可以通过已经计算过的对称位置子回文串对称中心(橙色箭头)得到当前回文半径,也就是1.

2、当前中心在回文串的对称位置下的子回文串超出了回文串的范围

如果对称位置下的子回文串并不完全被包含在回文串内,这种情况下不能直接将对称位置的回文半径赋值。但由于回文串的性质,我们可以保证包含在回文串内部的子串一定是回文串,则该种情况下当前位置的回文半径就是当前位置到回文串边缘的距离。

当前我们计算到绿色箭头时,对称位置的Pi = 2,但当前位置距离最大回文串的边界只有1,则只能将其赋值为1。

3、当前中心已经不在回文串范围之内了

这种情况下,一切都是未知的,只能用中心拓展算法来进行计算,也就是将该中心初始化为1,并进行中心拓展算法。

四、代码实现

虽然上面啰里啰嗦讲了一大堆,但实际代码非常简单,可以说理解了之后不用记模板随便敲的那种。

string s, str;          //s为原字符串,str为添加字符后的字符串
int P[N];               //保存每个字符的回文半径
void add() {str+='^';for (int i = 0; i < s.size(); i++) {str += '#';str += s[i];}str+='#';str+='@';
}void manacher() {int R = 0, mid = 0;for (int i = 1; i < str.size() - 1; i++) {P[i] = R > i ? min(P[2 * mid - i], R - i) : 1;   //进行三种情况的判断while (str[i + P[i]] == str[i - P[i]]) P[i]++;  //中心拓展if (i + P[i] > R) {                               //如果当前回文串已经覆盖到了原先没有覆盖到的地方,则更新标记R = i + P[i];mid = i;}}

最后放一道模板题
最长回文


manacher介绍及图文讲解(用于求解最长回文子串)相关推荐

  1. 求解最长回文子串----Manacher 算法

    最长回文子串问题:给定一个字符串,求它的最长回文子串长度. 如果一个字符串正着读和反着读是一样的,那么我们称之为回文串.例如:abba.aaaa.abvcba.123321等 暴力法:遍历字符串的所有 ...

  2. Manacher's algorithms(马拉车算法)最长回文子串

    最长回文子串 https://leetcode-cn.com/problems/longest-palindromic-substring/ 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 ...

  3. Leetcode-最长回文子串(包含动态规划以及Manacher算法)

    原文地址: https://www.cnblogs.com/mini-coconut/p/9074315.html 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000 ...

  4. 【最长回文子串】Manacher算法详解

    写在前面 manacher算法解决最长回文子串以及变形问题的时间复杂度为O(n). 如果你想囫囵吞枣,只需要使用到该算法,你可以直接把代码拿走:但如果你想深入了解这个算法的工作原理和关键部分解读,还是 ...

  5. 怎么判断一个字符串的最长回文子串是否在头尾_LeetCode 5 迅速判断回文串的Manacher算法...

    本文始发于个人公众号: TechFlow 题意 Given a string s, find the longest palindromic substring in s. You may assum ...

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

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

  7. LeetCode 5. Longest Palindromic Substring 最长回文子串 Python 四种解法(Manacher 动态规划)

    Longest Palindromic Substring 最长回文子串 学习笔记 1. Brute method 第一种方法:直接循环求解,o(n2)o(n^2) class Solution:de ...

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

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

  9. Manacher 求最长回文子串算法

    Manacher算法,是由一个叫Manacher的人在1975年发明的,可以在$O(n)$的时间复杂度里求出一个字符串中的最长回文子串. 例如这两个回文串"level"." ...

最新文章

  1. 白盒测试黑盒测试和单元测试集成测试和系统测试的关系
  2. 目标检测算法综述 | 基于候选区域的目标检测器 | CV | 机器视觉
  3. MVC、 MVP、 MVVM之间的区别
  4. 详解CSS选择器、优先级与匹配原理
  5. Smobiler 4.4 更新预告 Part 1(Smobiler能让你在Visual Studio上开发APP)
  6. [014]模板-模板实参推导
  7. 【算法】剑指 Offer 30. 包含min函数的栈
  8. Spring→事务、隔离级别、事务传播行为、编程式事务控制、XML配置声明式事务(原始方式)、XML配置声明式事务(基于tx/aop)、@注解配置声明式事务、优势总结
  9. 必应词典的使用和分析
  10. windows下如何创建bat文件
  11. win10文件服务器ssd当缓存盘,Win10开启写入缓存策略来提高SSD固态硬盘性能
  12. 如何通过iPhone或Android手机制作自己的QR码
  13. c1报考驾驶证网站php删除,c1驾驶证有违章,c1驾驶证免三种违章
  14. android 背景描边,Android告别使用shape标签,自定义实现圆角、背景色、描边Button...
  15. Opencv(C++)笔记--打开摄像头、保存摄像头视频
  16. Win10添加右键菜单以管理员方式打开cmd命令行
  17. Qiime2最全安装教程--包教包会,可私信远程免费帮装
  18. 苹果xr十大隐藏功能_别再说苹果“悬浮球”功能不好用,隐藏的实用小技巧,每天用得上...
  19. TPS5430降压电路,TPS5430芯片介绍
  20. 【抓包工具】实战:WireShark 捕获过滤器的超全使用教程

热门文章

  1. JS中sort方法排序
  2. PROTECTION_MODE is UNPROTECTED at standby database 分析
  3. $.ajaxSetup({}) --- js ajax统一配置
  4. Android studio 微信登录时碰到的坑
  5. 云存储运营情况两极化 一半是冰山一半是火焰
  6. python turtle图片保存eps_python – 将乌龟图形保存到.eps文件时,背景颜色显示在屏幕上但不保存在.eps文件中...
  7. python中glob模块怎么下_如何安装“glob”模块?
  8. 重新理解“充要条件”
  9. stratascratch 4 Finding User Purchases
  10. Linux服务器之lrzsz命令小记