Manacher
描述
给定一个长度为 
解释
显然在最坏情况下可能有 
但是关于回文串的信息可用 一种更紧凑的方式 表达:对于每个位置 
举例来说,字符串 
字符串 
因此关键思路是,如果以某个位置 
一个令人惊讶的事实是,存在一个复杂度为线性并且足够简单的算法计算上述两个「回文性质数组」
解法
总的来说,该问题具有多种解法:应用字符串哈希,该问题可在 
但是这里描述的算法 压倒性 的简单,并且在时间和空间复杂度上具有更小的常数。该算法由 Glenn K. Manacher 在 1975 年提出。
朴素算法
为了避免在之后的叙述中出现歧义,这里我们指出什么是「朴素算法」。
该算法通过下述方式工作:对每个中心位置 
该算法是比较慢的:它只能在 
该朴素算法的实现如下:
实现
| 1 2 3 4 5 6 7 8 9 10 11 12 13 |  | 
| 1 2 3 4 5 6 7 8 9 10 |  | 
Manacher 算法
这里我们将只描述算法中寻找所有奇数长度子回文串的情况,即只计算 
为了快速计算,我们维护已找到的最靠右的子回文串的 边界 
过程
现在假设我们要对下一个 
- 如果 - 因此我们将连续地增加 - 现在考虑 - 然而有一个 棘手的情况 需要被正确处理:当「内部」的回文串到达「外部」回文串的边界时,即 - 实际上,为了正确处理这种情况,我们应该「截断」回文串的长度,即置 - 该种情况的图示如下(以 - 该图示显示出,尽管以 
最后,仍有必要提醒的是,我们应当记得在计算完每个 
同时,再让我们重复一遍:计算偶数长度回文串数组 
Manacher 算法的复杂度
因为在计算一个特定位置的答案时我们总会运行朴素算法,所以一眼看去该算法的时间复杂度为线性的事实并不显然。
然而更仔细的分析显示出该算法具有线性复杂度。此处我们需要指出,计算 Z 函数的算法 和该算法较为类似,并同样具有线性时间复杂度。
实际上,注意到朴素算法的每次迭代均会使 
Manacher 算法的另一部分显然也是线性的,因此总复杂度为 
Manacher 算法的实现
分类讨论
为了计算 
| 1 2 3 4 5 6 7 8 9 10 11 12 |  | 
| 1 2 3 4 5 6 7 8 9 10 11 |  | 
计算 
| 1 2 3 4 5 6 7 8 9 10 11 12 |  | 
| 1 2 3 4 5 6 7 8 9 10 11 |  | 
统一处理
虽然在讲解过程及上述实现中我们将 
给定一个长度为 
对于字母间的 
注意到,在对 
上述结论建立了 
由于该统一处理本质上即求 
练习题目
本页面主要译自博文 Нахождение всех подпалиндромов 与其英文翻译版 Finding all sub-palindromes in 
本页面最近更新:2025/10/16 08:21:12,更新历史
发现错误?想一起完善? 在 GitHub 上编辑此页!
本页面贡献者:Ir1d, Enter-tainer, iamtwz, cesonic, Henry-ZHR, Tiphereth-A, Xeonacid, abc1763613206, Alisahhh, aofall, c-forrest, CamberLoid, chenhongqiao, CoelacanthusHex, fseasy, gi-b716, HeRaNO, ksyx, LeoJacob, Marcythm, Menci, ouuan, pengxurui, Persdre, shawlleyw, shuzhouliu, sshwy, StudyingFather, TrisolarisHD, Wsuika, XPZhen, YurianStormrage
本页面的全部内容在 CC BY-SA 4.0 和 SATA 协议之条款下提供,附加条款亦可能应用