2018 Summer Manacher(马拉车)算法 C和C++版

本文介绍了Manacher算法,一种用于寻找字符串中最长回文子串的线性时间复杂度算法。通过在字符串中插入特殊字符,将所有字符串转化为奇数长度,然后利用已知的回文信息来优化搜索过程。文中提供了C和C++的模板代码,并推荐使用C版本以避免某些情况下可能出现的超时问题。此外,还提到了一个在线评测平台上的相关问题供读者实践。
摘要由CSDN通过智能技术生成

最长回文子串

如果给你一个字符串abcbcbd,这个字符串里所包含的最长的回文子串是什么呢?毫无疑问,是bcbcb,它的长为6,
我们给出一个暴力简洁的算法:遍历整个字符串,对于每一个字符,都向左和右边找相等的字符,每次更新最大值,直到遍历完成。这样的算法看似简单,但是会遇到一个问题:对于奇数长度的回文串好处理,但对于偶数长度的回文串就比较麻烦。同时,这种算法的最坏复杂度为n^2,我们需要更加高效的算法。于是,“马拉车算法”,也就是Manacher算法就诞生了。

Manacher算法

在计算机科学中,最长回文子串或最长对称因子问题是在一个字符串中查找一个最长的连续的回文的子串,例如“banana”最长回文子串是“anana”。最长回文子串并不一定是唯一的,比如“abracadabra”,没有超过3的回文子串,但是有两个回文字串长度都是3:“ada”和“aca”。在一些应用中,我们求出全部的极大回文子串(不被其他回文串包含的回文子串)。

Manacher发现了一种线性时间算法,可以在列出给定字符串中从任意位置开始的所有回文子串。并且,Apostolico, Breslauer & Galil发现,同样的算法也可以在任意位置查找全部极大回文子串,并且时间复杂度是线性的。因此,他们提供了一种时间复杂度为线性的最长回文子串解法。另外,Jeuring (1994)[3], Gusfield (1997)发现了基于后缀树的算法。也存在已知的高效并行算法。
Manacher算法的算法原理,是在每两个字符之间,都插入#号,这样每个字符串都会变成奇数长度的字符串,同时,要在首位插入无关字符$,防止#和开头的#配对

abcbcbd
$#a#b#c#b#c#b#d#

对于每一个字符i,我们先判断它是否已经被包括在前面已经计算能包括住i的整个最长回文串里面,如果在里面,那么以它关于前一个最长回文串的中点id对称的点j为中心的最长回文长度应该已经计算出来了,如果以那个j为中心的的最长回文串已经包括在在计算好的最长回文串里面,那么我们有p[id-(i-id)]=p[i] 也就是p[j]=p[i]这段话看起来很拗口,但这也是manacher算法的重点

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值