Manacher算法解析

简介: Manacher算法解析

前言

Manacher算法目前了解到的适用范围只有求回文字符串。以下的所有解析也都会围绕求最大回文字符串来展开(求最大回文子串)。


什么是回文字符串?

回文字符串就是如“abba”,"abcba",这种围绕中心完全对称的字符串。

题目:在字符串里求出他的最大回文子串

如:12323,他的最大回文子串就是232和323。

接下来我们引入几个概念  对称中心,顾名思义就是对称最中心的那个数,比如121的对称中心就是2.因为我们这里需要把对称中心由一个数字具体表示,所以我们没法表示偶数数量的对称中心(比如1221的对称中心是22中间的对称轴)。那这里怎么解决呢?在每个数字的两边插入任意相同的字符(为什么是任意呢?因为原先对称的串在插入对称的字符后依然对称,所以随便插入什么字符都不会影响原先的结果),这里以插入#举例,插入后的效果是这样的。

插入完之后原来偶数数量对称的串都会变成奇数,并且也不会产生新的对称字符串(具体不理解的手画一遍就懂了),并且我们根据变化之后的(字符串长度/2)就可以得到原来字符串的长度了。

这时候可以用一种暴力解法来完成功能,遍历一遍数组,遍历过的每个元素都执行一遍操作:检验遍历过的元素的左右两边是否相等,如果相等则继续往外检验是否相等直到遇到左右不相等的字符为止或者碰到数组的边界为止。(举个例子:看上面那幅图,当我遍历到b时,我会检测b左边一位和b右边一位是否相等,这里是相等所以我继续将往左两位和往右两位进行比较)。这样就可以得到我们以该字符为中心的回文字符串的长度。然后再拿变量去记录最长的长度和下标,我们就能得到最终最长子字串的长度了。虽然这样已经能够实现功能,但他还有能够优化的地方,Manacher算法就是在这的基础上优化的

为了后面的运算能够快捷,我们需要申请一个长度等于加#后长度的数组,用来存储已经遍历过的每个位置的(中心的最长子字符串长度/2)。这里为什么要除以2呢,不是因为之前加过#要算回原来的大小,而是我们后面需要知道串伸向最右边的那个点(先不用知道为什么),而我们现在已经有了中心点的下标了,这时候直接加上一半的长度就可以得到该子串最右边的坐标了。

现在开始我们进行Manacher算法的讲解。

第一种情况   maxRight(遍历过的回文子串达到过最右的位置,一开始是0)小于现在所遍历到的位置,那就按照之前的解法一个个的遍历并记录每个的最大长度/2并更新maxRight.

第二种情况 maxRight大于现在所遍历到的位置。那么这时候将再分成三种情况。这里我们设当前遍历到的元素为 i,子字符串达到最右边的距离为maxRight,达到maxRight的子串中心center,i关于center的对称点 j,还有记录之前所遍历所有元素的最长臂长long[]从此以后臂长就是最大长度/2)

maxRight - i > long[j]

如图,假设这的的long[j] = 1,那么我们可以直接得到long[i] = 1且不需要做额外的对比。这是为什么呢?因为在maxRight内,i两边的内容和j两边的内容是完全相等的(因为关于center对称),而 j处的最大子串由不超过center的子串(由式子得出来的),所以long[i] = long[j]

② maxRight - i = long[j]

这里直接说结论,当相等时,检测i的最长子串可以直接从maxRight右边开始,maxRight左边至i的位置一定是回文的(因为j与i对称且j在maxRight'之前都是对称),然后maxRight的右边由于是为检验过的区域所以不知道能不能与i组成回文,只要直接从maxRight的右边检测就行

③ maxRight - i < long[j]

当满足上述式子时,是不是可以直接从maxRight右边开始检测呢?不必,因为这时候的结论是long[i] = maxRight - i ,这是因为如果这时候i的回文串能再往外多一个,就说明那个点与j在maxright'左边的那个点相等了,那就满足了center的中心回文的条件,这是矛盾的。所以这个时候long[i] = maxRight - i

上述的几种情况是可以进行合并的,可观察①和③。当maxRight - i > long[j] 时 long[i] = long[j],当maxRight - i < long[j] 时 long[i] = maxRight - i,再看②,是直接long[i] = long[j]然后再往后搜索。那我们就可以合并这三个式子为long[i] = min(maxRight - i,long[j])并再往后搜索

接下来就是重复上面的操作,记得每算完一个元素在对应的long里写进去他的臂长,也要及时修改maxRight的值。


总结

搜索最大回文子串,当i大于maxRight时,按照暴力解法从中心往外拓展搜索并记录搜索过位置的long[i]和maxRight;i小于maxRight时,long[i] = min(maxRight - i,long[j])并再往后搜索。

复杂度对比,直接暴力解发的时间复杂度是O(n^3),以搜索子串中心为目的的暴力解发时间复杂度是O(n^2),动态规划时间复杂度为O(n^2),Manacher算法的时间复杂度是O(n),空间复杂度是O(n)。


相关文章
|
4月前
|
存储 算法 安全
如何控制上网行为——基于 C# 实现布隆过滤器算法的上网行为管控策略研究与实践解析
在数字化办公生态系统中,企业对员工网络行为的精细化管理已成为保障网络安全、提升组织效能的核心命题。如何在有效防范恶意网站访问、数据泄露风险的同时,避免过度管控对正常业务运作的负面影响,构成了企业网络安全领域的重要研究方向。在此背景下,数据结构与算法作为底层技术支撑,其重要性愈发凸显。本文将以布隆过滤器算法为研究对象,基于 C# 编程语言开展理论分析与工程实践,系统探讨该算法在企业上网行为管理中的应用范式。
129 8
|
4月前
|
存储 监控 算法
解析公司屏幕监控软件中 C# 字典算法的数据管理效能与优化策略
数字化办公的时代背景下,企业为维护信息安全并提升管理效能,公司屏幕监控软件的应用日益普及。此软件犹如企业网络的 “数字卫士”,持续记录员工电脑屏幕的操作动态。然而,伴随数据量的持续增长,如何高效管理这些监控数据成为关键议题。C# 中的字典(Dictionary)数据结构,以其独特的键值对存储模式和高效的操作性能,为公司屏幕监控软件的数据管理提供了有力支持。下文将深入探究其原理与应用。
89 4
|
5月前
|
机器学习/深度学习 监控 算法
员工上网行为监控软件中基于滑动窗口的C#流量统计算法解析​
在数字化办公环境中,员工上网行为监控软件需要高效处理海量网络请求数据,同时实时识别异常行为(如高频访问非工作网站)。传统的时间序列统计方法因计算复杂度过高,难以满足低延迟需求。本文将介绍一种基于滑动窗口的C#统计算法,通过动态时间窗口管理,实现高效的行为模式分析与流量计数。
125 2
|
7月前
|
存储 算法 安全
.NET 平台 SM2 国密算法 License 证书生成深度解析
授权证书文件的后缀通常取决于其编码格式和具体用途。本文档通过一个示例程序展示了如何在 .NET 平台上使用国密 SM2 算法生成和验证许可证(License)文件。该示例不仅详细演示了 SM2 国密算法的实际应用场景,还提供了关于如何高效处理大规模许可证文件生成任务的技术参考。通过对不同并发策略的性能测试,开发者可以更好地理解如何优化许可证生成流程,以满足高并发和大数据量的需求。 希望这段描述更清晰地传达了程序的功能和技术亮点。
731 14
.NET 平台 SM2 国密算法 License 证书生成深度解析
|
4月前
|
存储 监控 算法
内网监控桌面与 PHP 哈希算法:从数据追踪到行为审计的技术解析
本文探讨了内网监控桌面系统的技术需求与数据结构选型,重点分析了哈希算法在企业内网安全管理中的应用。通过PHP语言实现的SHA-256算法,可有效支持软件准入控制、数据传输审计及操作日志存证等功能。文章还介绍了性能优化策略(如分块哈希计算和并行处理)与安全增强措施(如盐值强化和动态更新),并展望了哈希算法在图像处理、网络流量分析等领域的扩展应用。最终强调了构建完整内网安全闭环的重要性,为企业数字资产保护提供技术支撑。
124 2
|
5月前
|
存储 监控 算法
员工电脑监控场景下 Python 红黑树算法的深度解析
在当代企业管理范式中,员工电脑监控业已成为一种广泛采用的策略性手段,其核心目标在于维护企业信息安全、提升工作效能并确保合规性。借助对员工电脑操作的实时监测机制,企业能够敏锐洞察潜在风险,诸如数据泄露、恶意软件侵袭等威胁。而员工电脑监控系统的高效运作,高度依赖于底层的数据结构与算法架构。本文旨在深入探究红黑树(Red - Black Tree)这一数据结构在员工电脑监控领域的应用,并通过 Python 代码实例详尽阐释其实现机制。
107 7
|
5月前
|
存储 监控 算法
基于 C++ 哈希表算法的局域网如何监控电脑技术解析
当代数字化办公与生活环境中,局域网的广泛应用极大地提升了信息交互的效率与便捷性。然而,出于网络安全管理、资源合理分配以及合规性要求等多方面的考量,对局域网内计算机进行有效监控成为一项至关重要的任务。实现局域网内计算机监控,涉及多种数据结构与算法的运用。本文聚焦于 C++ 编程语言中的哈希表算法,深入探讨其在局域网计算机监控场景中的应用,并通过详尽的代码示例进行阐释。
110 4
|
5月前
|
存储 算法 物联网
解析局域网内控制电脑机制:基于 Go 语言链表算法的隐秘通信技术探究
数字化办公与物联网蓬勃发展的时代背景下,局域网内计算机控制已成为提升工作效率、达成设备协同管理的重要途径。无论是企业远程办公时的设备统一调度,还是智能家居系统中多设备间的联动控制,高效的数据传输与管理机制均构成实现局域网内计算机控制功能的核心要素。本文将深入探究 Go 语言中的链表数据结构,剖析其在局域网内计算机控制过程中,如何达成数据的有序存储与高效传输,并通过完整的 Go 语言代码示例展示其应用流程。
96 0
|
6月前
|
监控 算法 安全
基于 C# 的内网行为管理软件入侵检测算法解析
当下数字化办公环境中,内网行为管理软件已成为企业维护网络安全、提高办公效率的关键工具。它宛如一位恪尽职守的网络守护者,持续监控内网中的各类活动,以确保数据安全及网络稳定。在其诸多功能实现的背后,先进的数据结构与算法发挥着至关重要的作用。本文将深入探究一种应用于内网行为管理软件的 C# 算法 —— 基于二叉搜索树的入侵检测算法,并借助具体代码例程予以解析。
102 4
|
6月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

热门文章

最新文章

推荐镜像

更多
  • DNS