KMP
This commit is contained in:
@@ -8,6 +8,8 @@
|
||||
|
||||
- [替换空格](./substitute_spaces.md)
|
||||
- [翻转字符串里的单词](./reverse_words_in_a_string.md)
|
||||
- [左旋转字符串](./reverse_left_words.md)
|
||||
- [KMP](./kmp.md)
|
||||
|
||||
# 经典代码
|
||||
|
||||
|
35
notes/src/kmp.md
Normal file
35
notes/src/kmp.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# 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 详细代码实现与注释
|
7
notes/src/reverse_left_words.md
Normal file
7
notes/src/reverse_left_words.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# 左旋转字符串
|
||||
|
||||
[Leetcode](https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/)
|
||||
|
||||
涉及到字符串翻转/旋转,都可以考虑全剧翻转+局部翻转。
|
||||
|
||||
比如这道题就可以先翻转前半部分,再翻转后半部分,最后翻转整个字符串。
|
Reference in New Issue
Block a user