3.Manacher算法
3.1. manacher算法
给定一个字符串,找出其最长回文子串(子串在原字符串必须连续,子序列不一定要连续).
例如:
s=”1234”,最长回文长度为 1;
s=”12321”,最长回文长度为 5;
s=”12332”,最长回文长度为 4,即2332。
笨办法:遍历每一个字符,以该字符为中心向两边查找。其时间复杂度为O(n^2)。
Manacher算法:时间复杂度O(n)
a) 因为存在奇回文和偶回文,所以在字符串首尾以及中间插入特殊字符。偶回文则以特殊字符为中心,便可以一起处理。
例如:12332加入特殊字符后变成#1#2#3#2#3#,中心为红色的#号。
b) 定义一个辅助数组pArr,数组的第i点的值表示以i点为中心时的最大回文半径。
例如:
str | # | 1 | # | 2 | # | 3 | # | 3 | # | 2 | # |
---|---|---|---|---|---|---|---|---|---|---|---|
pArr | 1 | 2 | 1 | 2 | 1 | 2 | 5 | 2 | 1 | 2 | 1 |
无回文时,以自己为半径,所以半径为1。可以看出pArr-1为该点的最大回文长度。
c) 之后就是计算pArr数组的方法。首先以R记录到i点之前所有回文的右边界,index为该右边界所在回文的中心点,则左边界L=index-R。计算i点为半径的最大回文半径时,分四种情况:
1) i点在R的外部,则计算以i点为中心两边的回文长度;
2) i在R的内部,且i关于index的对称点i’的回文左边界在L内部,则i的最大回文半径和i’相等。
3) i在R的内部,且i关于index的对称点i’的回文左边界在L外部,则i的最大回文半径为R-i。
4) i在R的内部,且i关于index的对称点i’的回文左边界与L相等,则i的最小回文半径为R-i,直接比较最小半径以外的数值即可。
1 | /** |
3.2. Manacher算法扩展题目
给定一个字符串str1, 只能往str1的后面添加字符变成str2, 要求str2整体都是回文串且最短。
举例:str1 = ABC12321, 返回ABC12321CBA.
解法:重复manacher算法,当回文最右边界R到达str1的最后一位时,结束manacher算法,然后将str中L外部的子串逆序放在str1后面。