leetcode/notes/src/kmp.md

36 lines
1.2 KiB
Markdown
Raw Normal View History

2022-11-30 15:27:41 +00:00
# KMP
[代码随想录](https://programmercarl.com/0028.%E5%AE%9E%E7%8E%B0strStr.html)
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]` 一开始是相等的,但是当 `j``i` 都自增了 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 详细代码实现与注释