Manacher Algorithm(马拉车算法理解)

文章详细介绍了Manacher算法,一种用于查找字符串最长回文子串的线性时间复杂度算法。内容包括算法概述,字符串预处理方法,如何利用已知信息避免重复探测,以及时间复杂度分析。通过维护回文子串的边界信息,算法能够在处理过程中高效地更新和扩展回文串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Manacher Algorithm(马拉车算法)

一、 算法概述

Manacher算法(wikipedia)是求解字符串最长回文子串(Longest palindromic substring)问题的算法,它利用回文字符串和子回文字符串中观察到的一些特点,在线性时间内找出字符串的最长回文子串。这种算法能够尽可能利用之前探测回文子串时使用到的信息,进而避免一些不必要的探测。

Manacher算法,可以通过加入原本字符串中不存在的字符,将原本字符串回文子串长度为奇数和偶数两种情况统一起来。

Manacher算法会维护一个已经探测过的回文子串右边界最大的边界值。无论之前的信息是否可以利用,如果要进行新的探测,都只需从这个维护的边界向右探测。如果出现右边界位置更大的回文子串,则对其进行更新,这样以来,只需要O(n)的时间即可找到最长回文子串。

二、算法过程分析

1. 字符串预处理

字符串的两边相邻的两个字符之间 ,加入原本字符串中不存在的字符。将回文子串的长度为奇数和偶数统一起来。

  • 如原字符串为: ababa ,处理之后的字符串为:#a#b#a#b#a#

  • 为了能够使探测回文半径的循环遇到字符串边界时及时终止,退出循环,可在上述处理过的字符串两侧分别加入两个原字符串中没有且不同的字符。如上述处理过后的字符为: #a#b#a#b#a# ,首尾加入两个不同字符后为:$#a#b#a#b#a#!

  • 注意这里新增的符号只要能够达到目的即可,不一定与此处保持一致

2. 原字符串与新字符串的关联

原本字符串的最长回文子串的长度是新字符串最长回文子串长度的一半(对2取整)。

因为按照预处理的规则,新字符串中得到的回文子串,无论原本字符串中回文子串长度为奇数还是偶数,处理之后得到的新回文串长度都为奇数。

  • 如:abba 处理后得到 #a#b#b#a# 原长度为 4,新长度为 9。
  • 如:aba 处理后得到 #a#b#a# 原长度为 3,新长度为 7。

  • 不管原回文子串长度为奇为偶,加入的特殊字符(不含首尾两个)的个数总比其长度多 1,因此后续得到的回文串的长度总是奇数。

这样,由新的回文串得到原本的回文串长度,只需对 2 取整(/2)。

3. 如何利用之前已经获取到的信息?
3.1 维护数据

维护一个向量(或数组)f,其长度与处理之后得到的字符串相同,下标代表字符位置,值代表该位置回文半径长度。
维护两个变量:

  • 当前右边界位置最大的回文串的 回文中心位置,初始化为 0

  • 当前右边界位置最大的回文串的 右边界值,初始化为 0

3.2 按照规则进行初始化
3.2.1 如果当前计算的字符在前边得到的右边界值最大的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

草台班主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值