Manacher 计算最长回文串

本文介绍Manacher算法,一种用于寻找字符串中所有回文子串的高效算法,时间复杂度为O(n)。文章详细解释了如何通过在字符间插入分隔符统一奇偶长度回文串,并使用辅助数组rad[]来确定每个字符的最大回文半径。

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

转自 http://blog.sina.com.cn/s/blog_3fe961ae0101iwc2.html  

寻找字符串中的回文,有特定的算法来解决,也是本文的主题:Manacher算法,其时间复杂度为O(n)。

首先在每两个相邻字符中间插入一个分隔符,当然这个分隔符要在原串中没有出现过。一般可以用‘#’分隔。这样就非常巧妙的将奇数长度回文串与偶数长度回文串统一起来考虑了。

然后,我们需要一个辅助数组rad[],用rad[i]表示第i个字符的回文半径,rad[i]的最小值为1,即只有一个字符的情况,现在问题转变成如何求出rad数组。

假设现在求出了rad[1, ..., i],现在要求后面的rad值,再假设现在有个指针k,从1循环到rad[i],试图通过某些手段来求出[i + 1, i + rad[i] - 1]的rad值,其分析如下:

如图1所示,黑色的部分是一个回文子串,两段红色的区间对称相等。因为之前已经求出了rad[i - k],所以可以避免一些重复的查找和判断,有3种情况:

寻找字符串中最长回文——Manacher算法及其Java实现(POJ <wbr>3974)

图1

①  rad[i] - k < rad[i - k]

如图1,rad[i - k]的范围为青色。因为黑色的部分是回文的,且青色的部分超过了黑色的部分,所以rad[i + k]肯定至少为rad[i]-k,即橙色的部分。那橙色以外的部分就不是了吗?这是肯定的,因为如果橙色以外的部分也是回文的,那么根据青色和红色部分的关系,可以证明黑色部分再往外延伸一点也是一个回文子串,这肯定是不可能的,因此rad[i + k] = rad[i] - k。

②  rad[i] - k > rad[i - k]

如图2,rad[i-k]的范围为青色,因为黑色的部分是回文的,且青色的部分在黑色的部分里面,根据定义,很容易得出:rad[i + k] = rad[i - k]。根据上面两种情况,可以得出结论:当rad[i] - k != rad[i - k]的时候,rad[i + k] = min(rad[i] - k, rad[i - k])。

寻找字符串中最长回文——Manacher算法及其Java实现(POJ <wbr>3974)

图2

③  rad[i] - k = rad[i - k]

如图,通过和第一种情况对比之后会发现,因为青色的部分没有超出黑色的部分,所以即使橙色的部分全等,也无法像第一种情况一样引出矛盾,因此橙色的部分是有可能全等的。但是,根据已知的信息,我们不知道橙色的部分是多长,因此就需要再去尝试和判断了。

寻找字符串中最长回文——Manacher算法及其Java实现(POJ <wbr>3974)

 

转载于:https://www.cnblogs.com/Opaser/p/4497623.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值