Manacher算法

形象的被译为马拉车算法

这个算法用于处理简单的回文字符串的问题。可以在 \(O(n)\) 的复杂度内处理出每一个位置为中心的回文串的最长长度。

为了避免出现偶数长度的回文串,导致过多的分类讨论,我们预处理一下字符串。

例如:jeefy

我们可以预处理成 ^#j#e#e#f#y#$。(开始,间隔和结束符尽量不一样,并且不能出现在原序列中)

那么我们再定义一点点东西:

  • P[i] 指在处理后的字符串中,以 i 为中心的回文串的最大长度的半径(包括了 i)也就是说,处理后的串中,(i-P[i], i+P[i]) 这个开区间是一个回文串。

  • R 指我们已经搜索到的最右边界,M 指最右边界对应的中心

为了方便讲解,我们先考虑更朴素的算法:中心扩展法(名字来源LeetCode)。

其实思路很简单,我们以某一个点为中心向两边扩展,同时需要分类讨论奇数长度和偶数长度。

int expandAt(char * s, int l, int r) {
int len = strlen(s);
while (0 <= l && r < len && s[l - 1] == s[r + 1]) ++r, --l;
return r - l - 1;
}

未验证代码,注意甄别

其时间复杂度为 \(O(n^2)\) ,但是,在随机数据下,其表现接近于线性。毒瘤出题人当然不愿意了

所以,有了 Manacher 算法来优化。

其算法核心思想在于利用回文串的对称性,这样我们可以充分的利用其对称区间的信息。

如图:

若黑色区间是一个回文串,且黑色竖线为其中心已知红色区间是一个能向外扩展的最长回文串,那么很容易得知橙色的区间也是一个回文串,并且这个回文串对于这个中心是最长的

理解回文串的对称性,如果橙色的不是最长的,意味着对称过来红色的也不是最长的,与已知冲突。

那么我们考虑什么时候可以扩展出去?

如图,如果左侧对应的回文串左边界超过或者等于黑色部分的边界,那么,实际上,右侧只有橙色部分(黑色边界内)的信息是可以用的。

因为回文串的对称性并没有包括了黑色部分以外的信息,所以……

同理,如果右侧的中心已经在黑色部分以外了……那么也没有可用的信息,暴力扩展即可。

参考代码:

for (int i(1); i < n; ++i) {
p = R > i ? min(R - i + 1, P[(M<<1) - i]) : 1; // 可用信息
while (s[i + p] == s[i - p]) ++p; // 向两边扩展
if (i + p - 1 > R) M = i, R = i + p - 1; // 更新边界
P[i] = p;
}

复杂度证明:

我们考虑边界 R,从 0 更新到 n,总共变化了 n 次。

那么 R 什么时候被更新?

也就是第二种情况,可以向外扩展才可以更新 R,且每一次成功的扩展会使 R 变大一位。

如果是第一种情况,那么是无法向外扩展的,且 R 也不会改变。

也就是说,最多只会扩展 \(O(n)\) 次,所以,整个算法的复杂度为 \(O(n)\),常数非常小。


对于模板题:【模板】manacher 算法 - 洛谷

参考代码如下:


例题:SHOI2011 双倍回文

可以参考我的题解:[SHOI2011]双倍回文 题解 - jeefy - 博客园


那么 Mancher 是否只能用在字符串上?

可以发现的是 Manacher 算法其实和字符集的大小没有关系,并且只用到了相等与不等的关系。

这启发我们其实完全可以扩展 Manacher 的,处理更多的信息。

经典的一道题是:CF1080E,其中定义的是字符的集合的相等和不等关系,也就是从字符扩展到了字符的集合。这也可以通过哈希来判断,也就是扩展到整数上。

算法学习笔记(13): Manacher算法的更多相关文章

  1. 【学习笔记】Manacher算法

    本文部分图片来源 代码来源(代码是学姐哒.. 一.引入 Manacher算法是用来求最长回文子串的算法,时间复杂度O(n). 回文子串指的是''aacaa'',''noon'',这种正着反着读都一样的 ...

  2. 【算法学习笔记】Meissel-Lehmer 算法 (亚线性时间找出素数个数)

    「Meissel-Lehmer 算法」是一种能在亚线性时间复杂度内求出 \(1\sim n\) 内质数个数的一种算法. 在看素数相关论文时发现了这个算法,论文链接:Here. 算法的细节来自 OI w ...

  3. 算法学习笔记:Kosaraju算法

    Kosaraju算法一看这个名字很奇怪就可以猜到它也是一个根据人名起的算法,它的发明人是S. Rao Kosaraju,这是一个在图论当中非常著名的算法,可以用来拆分有向图当中的强连通分量. 背景知识 ...

  4. 算法学习笔记:Tarjan算法

    在上一篇文章当中我们分享了强连通分量分解的一个经典算法Kosaraju算法,它的核心原理是通过将图翻转,以及两次递归来实现.今天介绍的算法名叫Tarjan,同样是一个很奇怪的名字,奇怪就对了,这也是以 ...

  5. Miller-Rabin 与 Pollard-Rho 算法学习笔记

    前言 Miller-Rabin 算法用于判断一个数 \(p\) 是否是质数,若选定 \(w\) 个数进行判断,那么正确率约是 \(1-\frac{1}{4^w}\) ,时间复杂度为 \(O(\log ...

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

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

  7. Johnson 全源最短路径算法学习笔记

    Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...

  8. 算法学习笔记(5): 最近公共祖先(LCA)

    最近公共祖先(LCA) 目录 最近公共祖先(LCA) 定义 求法 方法一:树上倍增 朴素算法 复杂度分析 方法二:dfs序与ST表 初始化与查询 复杂度分析 方法三:树链剖分 DFS序 性质 重链 重 ...

  9. C / C++算法学习笔记(8)-SHELL排序

    原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...

  10. GMM高斯混合模型学习笔记(EM算法求解)

    提出混合模型主要是为了能更好地近似一些较复杂的样本分布,通过不断添加component个数,能够随意地逼近不论什么连续的概率分布.所以我们觉得不论什么样本分布都能够用混合模型来建模.由于高斯函数具有一 ...

随机推荐

  1. Web3开发者技术选型:前端视角(next.js)

    引言 在现代Web开发的世界中,Web3技术的兴起为前端开发者开辟了新的可能性.Web3技术主要指的是建立在区块链基础上的分布式网络,使用户能够通过智能合约和去中心化应用(DApps)直接交互,而无需 ...

  2. Hologres+Hologres+Flink流批一体首次落地4982亿背后的营销分析大屏Flink流批一体首次落地4982亿背后的营销分析大屏

    简介: 本篇将重点介绍Hologres在阿里巴巴淘宝营销活动分析场景的最佳实践,揭秘Flink+Hologres流批一体首次落地阿里双11营销分析大屏背后的技术考验. 概要:刚刚结束的2020天猫双1 ...

  3. 21克:仅需3天,我们就用Quick BI搭建起数据驾驶舱

    ​简介:数智化并不仅仅是大型企业才需要去思考的课题,而是摆在所有企业面前的一个可选项.借助Quick BI搭建的数据分析体系,21克实现了销售.财务.供应链等多部门业务的数据化支撑,从一份份本地化的E ...

  4. 10个Bug环环相扣,你能解开几个?

    ​简介:由阿里云云效主办的2021年第3届83行代码挑战赛已经收官.超2万人围观,近4000人参赛,85个团队组团来战.大赛采用游戏闯关玩儿法,融合元宇宙科幻和剧本杀元素,让一众开发者玩得不亦乐乎. ...

  5. [FE] 关于网页的一些反爬手段的解析思路,比如 58 等

    这里主要是贴一些资料,有兴趣的可以再深入研究,比如做一些自动化库. www.cnblogs.com/TRHX/p/11740616.html blog.csdn.net/DzzzzzZzzzz/art ...

  6. [Contract] 一次搞懂 Solidity 的 using xx for xx

    using A for *;    # 把 A 的函数附给任意类型使用 using A for B; # 意思是把 A 中的方法附给 B 使用 使用上面的方式,那么在我们的合约中定义了 B 类型的变量 ...

  7. 记 dotnet 8.0.4 修复的 WPF 的触摸模块安全问题

    本文记录 dotnet 8.0.4 版本修复的 WPF 的触摸模块安全问题,此问题影响所有的 .NET 版本,修复方法是更新 SDK 和运行时 宣布安全漏洞地址: https://github.com ...

  8. dotnet 写一个支持层层继承属性的对象

    我最近在造一个比 Excel 差得多的表格控件,其中一个需求是属性的继承.大家都知道,表格里面有单元格,单元格里面允许放文本,文本可以放多段文本.本文的主角就是文本段落的样式属性,包括文本字体字号颜色 ...

  9. WPF 通过 Windows Template Studio 快速搭建项目框架和上手项目

    本文对新手友好.在咱开始一个新项目的时候,可以利用 Windows Template Studio 快速搭建整个项目的框架.搭建出来的框架比较现代化,适合想要快速开发一个项目的大佬使用,也适合小白入门 ...

  10. Kafka 监听器详解

    Kafka 监听器详解 Kafka Assistant 是一款 Kafka GUI 管理工具--管理Broker,Topic,Group.查看消费详情.监控服务器状态.支持多种消息格式. 目录 Kaf ...