最长回文子串-马拉车
目录
回文串是指是正着读和反着读都一样的字符串,比如abcba
。
最长回文子串是指在一个字符串中能找到的最长回文串,如这个字符串最长回文字串是最后6个字符:abacacbaaaab
用马拉车算法求一个串中的最长回文子串:
- 首先将字符串长度处理成奇数,如
"abbc"
处理成"$a#b#b#c#"
。 - 然后从左到右边遍历求出以每个字符为中心的回文半径
Mp
, 其中最大的那个回文半径就对应着最长的回文子串。
Manacher
算法实现如下:
图中id
表示如果以这个下标为中心,回文半径最远可以到达的位置是mx
(这表示区间(id,mx]
与[mx",id)
是对称的, id
位置就是对称轴)。
马拉车的思想是利用左边已经求出的回文半径,帮助计算右边的回文半径。如果我们要求下标i
的回文半径,那么:
2*id-i
指的就是是下标i
关于id
的对称位置i"
,(i
肯定在id
的右边,因为是从左往右遍历处理)
计算回文半径Mp[i]
:
-
如果
mx>i
(图1,2),即id
处的回文半径能够覆盖当前位置,那么i
关于id
的对称位置i"
一定也在以id
为中心的回文串中。i"
位于id
左边,所以i"
的结果前面已经算出来了,直接得出i"
的回文半径就是Mp[i"] = Mp[2*id-i]
。(图里左边的红色部分就是回文半径为
Mp[i"]
的回文串,右边是对称的部分)这时候计算
i
的回文半径还分两种情况:mx-i > Mp[2*id-i]
mx-i < Mp[2*id-i]
分别对应图1、2。
Mp[i]
的值选取两者中较小的那一个。因为图中只有同时被红色和绿色覆盖的,才关于
i
对称,其他的未知。 -
如果,
mx <= i
(图3),那么i
的回文半径只能通过一次次比较求得。
细节见代码,返回值是最长回文串长度。
|
|
例题
POJ3974 裸题