KMP匹配字符串
KMP匹配字符串
题目链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/submissions/
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1: 输入: haystack = “hello”, needle = “ll” 输出: 2
示例 2: 输入: haystack = “aaaaa”, needle = “bba” 输出: -1
KMP思路简介
KMP的主要思想是:在匹配时,如果遇到某个项不匹配,则尝试利用之前已经匹配过的结果,避免从头继续匹配。对于字符串匹配,可以做到只遍历一遍文本串就匹配出结果。时间复杂度总暴力循环的O(m*n)降低到O(m+n):匹配时间+生成Next数组的时间。
Next数组生成
next[i]表示:在模式串中,前i个(下标为0开始)字符组成的子串的 最长相同前后缀 的长度
- 最长相同前后缀:例:aabaa,最长相同前后缀为aa,长度为2。aabaab,最长相同前后缀为aab。
利用最长相同前后缀进行匹配:
例:文本串aabaabaafa,模式串aabaaf:
开始匹配,当文本串的第6个字符b和模式串的第6个字符f不匹配时,有:
- b和f不匹配
- b和f前面的字符是匹配的
- 模式串中f前面的字符a的next数组数值为2即aabaa的最长相同前后缀长度为2
- 模式串f的前两个字符aa = 文本串b的前两个字符aa = 模式串第0、第1个字符aa
- 模式串的前两个字符已经和文本串b的前两个字符aa匹配,无需继续比较,直接比较模式串的第三个字符b和文本串当前所停留的字符b是否相同
- 重复直到比较完毕
知道匹配原理后,可以生成next数组。因为next数组实际上模式串是自己和自己匹配的过程
1 | void forNext(int* next,string needle){ |
进行匹配
匹配的思路在上方已经说明。
1 | for(;i<haystack.size();i++){ |
文本串只需遍历一遍,模式串不匹配时回退到最大匹配部分之后继续匹配
整体代码
1 | class Solution { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 星辰微光的博客!




