Manacher算法
用于查找一个字符串的最长回文子串的线性算法
p[i]:以i为中心的回文串半径
从前往后扫,当扫到p[i]时已计算了p[1~i-1]
记录i+k前所有回文串中能延伸到的最右端位置,即p[i]+i
计算p[i+k]:
1. i+k不在前面任何回文串中(maxlen<i+k)
则初始化p[i+k]=1,然后向左右延伸
2. i+k被前面以i为中心的回文串包含(maxlen>i+k)
则i+k与i-k关于i对称,分三种情况:
① i-k回文串有一部分在i的回文串之外,则p[i+k]=p[i]-k
② i-k回文串全部在i的回文串内,则p[i+k]=p[i-k]
③ i-k回文串与i回文串左端重合,则p[i+k]=p[i-k],且可能继续增加,向左右延伸

总结: p[i+k]=min(p[i-k],p[i]-k)
while(s[i+k-p[i+k]]==s[i+k+p[i+k]]) ++p[i+k]
Tip: ·偶数长度的字符串中心为空,则在字符串中加入‘#’
如 abab --> #a#b#a#b#
·最长回文子串长度为maxlen-1
ans = [(maxlen-2)*2]/2+1 = maxlen-1
(-2):去掉左端#和中心字符
(*2):对称
(/2):#与字符数量相等
(+1):加上中心字符
·令s[0]=‘*’,因为首尾s[0]和s[2*len+2]要插入不同的字 符,防止p[i]越界


浙公网安备 33010602011771号