# 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 详细代码实现与注释