KMP:
复杂度O(n + m)
T : ababcabcacbab
S : abcac
S
前缀 a ab abc abca
后缀 c ac cac baca
KMP:
首先是Next数组的初始化,
表示当前位的下一位如果失配,则当前位应该跳到的位置。
也就是最长的前后缀相等的长度(由于是从-1开始,严格来讲应该是长度-1)。
T :0 ~ n - 1,S : 0 ~ m - 1。
假设0前面存在一位-1,每次比较T[i] 与 S[j + 1],是否相等,此时S[0 ~ j] 已经与T[i - j - 1 ~ i - 1] 相匹配,如果相等,则继续匹配,如果不相等则j = Next[j],此时跳转到与S[k ~ j] 相等的前缀 S[0 ~ j - k]上进行匹配,如果Next[j] = -1,说明没有相等的前缀,则下一次循环,i + 1后,S从0开始与T进行比较。
例如:
T : acdacdace
S: acdace
acdace
Manacher:
求最长回文串
首先把奇数长度的串和偶数长度的串统一成奇数长度的串,在两个字符之间加没有出现过的字符,例如#。
在第一位前面加上&
abccba ----> &#a#b#c#c#b#a#
mid:回文串中心位置
p[i]代表从i位扩展的最大的回文半径
mr :当前最长回文串扩展的最靠右的坐标(实际上是最大的下一位)
分两种情况:
1、i在mr内,且i位中心的回文串扩展最远位置小于mr,那么p[i]等于i关于mid的对称点j的p[j]。
2、如果在扩展的时候,超过了mr,则p[i] = mr - i,然后在向外继续扩展,
我们发现在加了#后,p[i]实际等于以i为中心的回文串长度 -1。
减一是因为在回文串的两端为#,需要减去。