catalog
相同前后缀
kmp的本质,就是 相同前后缀
所谓 相同前后缀:
a b c d e f g h
前缀prefix: [a, b, ...]
后缀suffix: [..., g, h]
比如最长相同前后缀的长度为3
即表示: [a, b, c] == [f, g, h]
且规定: 最长相同前后缀的长度 != n,否则无意义
因为,对于任意一个串s: 长度为n的前缀s == 长度为n的后缀s
所以, 我们这里讨论的 一个串的“最长前后缀长度”,其实严格说是“次长”,即必须长度 < n
一个长度为n的串,他最长前后缀长度 所有可能是: [0, n-1]
长度为偶数6的串 | 最长前后缀长度 | 长度为奇数5的串 | 最长前后缀长度 |
---|---|---|---|
aaaaaa | 5(aaaaa) | aaaaa | 4(aaaa) |
ababab | 4(abab) | ababa | 3(aba) |
abcabc | 3(abc) | abcde | 0() |
如果s中,没有与s[1]相同的字符,那么s的最长前后缀肯定为0,因为前后缀要匹配,至少第一个字符要相同
O(n)构造 最长前后缀 数组
已知s串[1,2,3,..n]的前后缀长度为k,求[1,2,3,..,n,n+1]串的前后缀长度 '简称len为 最长前后缀长度 '
s: 1, 2, 3, 4, 5, 6, ..., n
s[1,n]的前缀: [1 2 3 ... k-2 k-1 k]
s[1,n]的后缀: [. . . ... n-2 n-1 n] ' 这俩是 对应上下位相同的 '
当此时新来了一个 [n+1]元素时,找s[1, n+1]的最长前后缀,即:
s[1, n+1]的前缀pre: [1 2 3 ... j-1 j ]
s[1, n+1]的后缀suf: [. . . ... n n+1]
目的是: 使pre==suf,且长度最长
由于,前缀pre的头[1] 和 后缀的尾[n+1] 是固定死的, 这是前后缀的要求
即,因为suf[n+1]是固定死的,让suf最长,即让[...n](suf去除[n+1]后的部分)最长
' 即找最长的: pre[1 2 3 ... j-1] 和 suf[... n-1 n] '
可以发现,他的答案,就是 s[1,n]的len
但需要有个前提: pre[j] == suf[n+1] ' j就是 s[1,n]的len '
即if( s[ (s[1,n]的len) + 1 ] == s[ n+1 ] )
s[1,n+1]的len = s[1,n]的len + 1
' 即,新加入1个元素[n+1], 整个串的len 最大是 原来串的len+1 '
关键是当else的情况,
由于,s[j