Manache算法

  定义:是一个判断回文子串的算法,我们结合例题解释:

        题目:给定一个长度为 n 的字符串 S,求其最长回文子串 一个字符串是回文的,当且仅当反转后的串与原串完全相等

   分析:对于这个题目,有三种主流思路:

        一:Hash+二分

            计算字符串的前缀hash值

            枚举中点,二分回文字串的长度

            时间复杂度:$O(nlogn)$

          二:回文自动机

         复杂度是线性的,但是编程复杂度极高,思维难度极高。

          三:Manache算法

       复杂度是线性的,思维难度低,编程难度低


讲解Manache方法

      对于Manache算法,我们先考虑朴素做法:枚举回文串中心,然后向两边扩展,这样的复杂度是$O(N^2)$的,

      但是类比KMP算法,我们在朴素算法中,没有考虑到已经计算的部分对于之后结果的贡献,朴素方法的突破口就在这里了。

      考虑优化:由于回文串长度分奇偶,有点麻烦,所以,我们考虑在每个字符中间插入一个'#'字符,来保证字符串的奇性。特别的,在字符串前两个字符,插入\$和#,对于\$的作用是:防止数组越界,既下文代码中的whie()函数,来确保其遇到字符串开头立即停止(因为对于$字符,其为唯一的,不可能有字符与其匹配)。

      我们引入辅助数组$len[i]$ 来表示以$i$为中心,最大回文串的半径,显然的,对于每一个$len[i]$,$len[i]-1$就是原来回文串的长度,我们结合一个样例来说明:

      原字符串:$   #   A   #   B   #   A   #   A   #    B    #

      $len$数组  1   1   2    1   4    1   2     2   2    1   2    1

      原来的最长回文串是$3$ 也就是$len[4]-1$ (从0开始标号)。

      对吧?

      接下来的问题,就是如何计算$len$数组了 , 这确实是个问题,不过我们可以通过下面的办法解决:

      考虑$len[i]$ 以及当前求出的回文右边界$mx$ , $id$ 是对应的回文中心,如果$i<mx$ 则附上初值$min{mx-i,p[j]}$,其中,$j$是$i$关于$id$的对称坐标,通过中点坐标公式,我们可以得出:$j=id*2-i$ 。

      否则($i>=mx$)附上初值$len[i]=1$.

      然后,向两边扩展就好了。可以结合下面的图像理解:

      

         带有下划线的部分,是已经计算得出的回文串。

代码实现:

1 void Manache() {
2     int pos=0,mx=0;
3     for(register int i=1;i<=n;++i) {
4         len[i]=i<mx?min(len[(pos<<1)-i],mx-i):1;
5         while(b[i-len[i]]==b[i+len[i]]) len[i]++;
6         if(i+len[i]>mx) mx=i+len[i],pos=i;
7     }
8 }

View Code

转载于:https://www.cnblogs.com/Syameimaru/p/9310883.html

【文文殿下】Manache算法-学习笔记相关推荐

  1. 【文文殿下】网络流学习笔记

    最大流算法 Dinic 割 一个网络的割:存在一个边集,删去集合里的边时,S-T不再连通 最小割 所有割中边权之和最小的 最小割-最大流定理 最小割等于最大流 二分图匹配 \(M\)为边集\(E\)的 ...

  2. 大顶堆删除最大值_算法学习笔记(47): 二叉堆

    堆(Heap)是一类数据结构,它们拥有树状结构,且能够保证父节点比子节点大(或小).当根节点保存堆中最大值时,称为大根堆:反之,则称为小根堆. 二叉堆(Binary Heap)是最简单.常用的堆,是一 ...

  3. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

  4. 数据结构与算法学习笔记之 从0编号的数组

    数据结构与算法学习笔记之 从0编号的数组 前言 数组看似简单,但掌握精髓的却没有多少:他既是编程语言中的数据类型,又是最基础的数据结构: 一个小问题: 为什么数据要从0开始编号,而不是 从1开始呢? ...

  5. 输出dag的所有拓扑排序序列_算法学习笔记(53): 拓扑排序

    拓扑排序是对DAG(有向无环图)上的节点进行排序,使得对于每一条有向边 , 都在 之前出现.简单地说,是在不破坏节点 先后顺序的前提下,把DAG拉成一条链.如果以游戏中的科技树(虽然名字带树,其实常常 ...

  6. 算法学习笔记:对指定金额计算最少钞票数

    算法学习笔记:对指定金额计算最少钞票数 一.引出问题 财务人员给员工发工资时经常遇到这样一个问题,即根据每个人的工资额(以元作为单位)计算出各种面值的钞票的张数,且要求总张数最少.例如,某职工工资为3 ...

  7. matlab中x从0到5不含0,关于MATLAB的数学建模算法学习笔记

    关于MATLAB的数学建模算法学习笔记 目录 线性规划中应用: (3) 非线性规划: (3) 指派问题;投资问题:(0-1问题) (3) 1)应用fmincon命令语句 (3) 2)应用指令函数:bi ...

  8. 机器学习篇01:在线学习的支持向量机算法学习笔记

    在线学习的支持向量机算法学习笔记 oisvm算法实现说明 oisvm算法实现说明 % 本程序是用于实现基于在线学习的调制信号识别的程序 % % % 第一步:调制信号的生成 % 首先是7个信号:2ASK ...

  9. 数据结构与算法学习笔记之 提高读取性能的链表(上)

    数据结构与算法学习笔记之 提高读取性能的链表(上) 前言 链表(Linked list)比数组稍微复杂一点,在我们生活中用到最常见的应该是缓存,它是一种提高数据读取性能的技术,常见的如cpu缓存,浏览 ...

最新文章

  1. MSB600 cmd.exe 已退出,代码为3
  2. js中bind、call、apply函数的用法
  3. Char.IsDigit与Char.IsNumber的区别[转]
  4. windows编写linux脚本,Windows PowerShell:共享您的脚本 - 在脚本中编写 Cmdlet | Microsoft Docs...
  5. mysql数据库的新特性_【数据库】MySQL新特性归档介绍
  6. 塔菲克蓝牙适配器驱动_TAFIQ蓝牙适配器驱动下载|TAFIQ蓝牙适配器驱动 v4.0 最新免费版 下载 - 巴士下载站...
  7. vs201中debug和release两个版本的区别
  8. Java 文件上传 三种方式
  9. Markdown 教程
  10. luogu P5064 [Ynoi2014] 等这场战争结束之后
  11. 把撒哈拉沙漠变成一个太阳能农场,这可能吗?
  12. ecshop小京东产品后台版权及logo修改
  13. uni.showToast appd端不起作用
  14. 杰理之设置立体声输出,播左右声道歌曲后DAC没有声音或声音变小
  15. 【AI视野·今日CV 计算机视觉论文速览 第231期】Mon, 5 Jul 2021
  16. RAD0.1 RB.1/.2
  17. snort create mysql_安装Snort
  18. Artery6基本操作流程
  19. Java实现远程桌面连接
  20. Three.js_解决谍影锯齿闪烁重影模型的方法

热门文章

  1. 使用no-gui 模式执行分布式测试
  2. PHP file_get_contents() 函数
  3. webservice CXF入门服务端
  4. (第十三周)评论Final发布II
  5. Redis 实现用户积分排行榜
  6. 惹恼程序员的10件事
  7. 管理Shader——Shader概览
  8. HBase之KeyValueScanner
  9. Hive之管理表 外部表 分区表
  10. (35)Verilog HDL算术运算:取模、指数、对数