Manacher
一 、背景
1975年,Manacher发明了Manacher算法(中文名:马拉车算法),是一个可以在O(n)的复杂度中返回字符串s中最长回文子串长度的算法,十分巧妙。
让我们举个例子:
1.字符串:abbababa 最长回文子串:5(abbababa)
2.字符串:abcbbabbc 最长回文子串:7(abcbbabbc)
3.字符串:abccbaba 最长回文子串:6(abccbaba)
传统方法是,遍历每个字符,以该字符为中心向两边查找。时间复杂度为O(n^2),效率很差;
但是Manacher算法的时间复杂度可以达到O(n)!
下面让我们看看它是怎么做的的吧
二、算法过程分析
回文分为奇回文(ababa)和偶回文(abba),这里比较难以处理,我们使用一个骚操作(划重点)。
我们将字符串首尾和每个字符间插入一个字符(注意:这个自符在串中并未出现)例如:’#’ s='abbadcacda’先转化成s_new=$#a#b#b#a#d#c#a#c#d#a#\0’(加粗的是边界)
这样原串中的偶回文(abba)与奇回文(adcacda),变成了(#a#d#d#a#)与(#a#d#c#a#c#d#a#)两个奇回文。
定义数组p,用p[i]表示以i为中心的最长回文半径。再次举个例子
(图片是借鉴了他人的)
定义两个变量mx和id。mx就是以id为中心的最长回文右边界,也就是mx=id+p[id],随后我们需要mx做出它的最大贡献。
假设我们在求p[i](以i为中心的最长回文半径),如果i<mx(如上图),那么我们就用mx和j来更新到我们已知的可以更新的最大长度,代码如下:
if(i<mx)
p[i]=min(p[2