leetcode/notes/src/kmp.md

1.2 KiB

KMP

代码随想录

KMP 主要用在 pattern 匹配上。

比如给出一个字符串 s 和一个 pattern ,请找出 pattern 第一次在 s 中出现的下标。

最长公共前后缀

前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串;

后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串。

比如字符串 aaabcaaa 的最长公共前后缀是 aaa ,最长公共前后缀长度就是 3 。

前缀表

next[i] 表示 s[0...i] 这个子字符串的最长公共前后缀长度。

基本思路

i 代表 pattern 的前缀结尾,j 代表 s 的后缀结尾。

我们假设 pattern[0...j]s[i-j...i] 一开始是相等的,但是当 ji 都自增了 1 之后就不完全相等了,即末尾的 pattern[j]s[i] 不相同。

但是 pattern[0...j] 有一段前缀 pattern[0...k]s 的一段后缀 s[i-k...i] 相同。

那么我们可以从 pattern[k+1] 开始匹配。

这个时候我们需要让 j 回退到 k+1 。那么怎么做呢?

实际上 k+1 == next[j-1]

参考 s0028 详细代码实现与注释