题解 62| 流水他带走匹配的故事,改变了我们#kmp算法#
kmp算法
https://www.nowcoder.com/practice/bb1615c381cc4237919d1aa448083bcc
KMP算法简单实现(今天LNG 0:3 T1,该配合你演出的我演视而不见)
class Solution { public: /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 计算模板串S在文本串T中出现了多少次 * @param S string字符串 模板串 * @param T string字符串 文本串 * @return int整型 */ int kmp(string S, string T) { // write code here int s = S.size(),t = T.size(); //模式串比主串长的话 if (S.empty() || s > t) { return 0; } int res = 0,next[s-1]; //next[x]的意义是长度为x的前子串最长相同前后缀长度 next[0] = -1; //第0位设置成-1 表示需要右移被匹配字符指针 //先用双指针在模板内进行匹配 for (int pre = -1, now = 0; now < s; ) { if(pre == -1 || S[pre] == S[now]){ pre++; now++; //左右指针 next[now] = pre; }else { pre = next[pre]; } } //现在模式串和文本串进行匹配 for (int patt = 0,now = 0; now < t; ) { if (patt == -1 || S[patt] == T[now]) { patt++; now++; //大小指针 if (patt == s) {//完全匹配的情况 res++; patt = next[patt]; } }else { patt = next[patt]; } } return res; } };
KMP算法和朴素匹配(也称为暴力匹配)的区别
1. 匹配方式不同:
朴素匹配:从文本串的第一个字符开始,依次与模式串的每个字符进行比较,如果不匹配则移动文本串的指针,继续从下一个字符开始比较。
KMP算法:通过预处理模式串的next数组,根据已经匹配的前缀信息,确定模式串的下一个比较位置,从而避免重复匹配已经匹配过的字符。
2. 时间复杂度不同:
朴素匹配的时间复杂度为O(m*n),其中m为模式串的长度,n为文本串的长度。
KMP算法的时间复杂度为O(m+n),其中m为模式串的长度,n为文本串的长度。由于KMP算法避免了重复匹配,所以在大部分情况下,KMP算法的效率要高于朴素匹配。
3. 空间复杂度不同:
朴素匹配的空间复杂度为O(1),不需要额外的空间。
KMP算法的空间复杂度为O(m),需要额外的空间来存储模式串的next数组。
总结:KMP算法通过预处理模式串的next数组,可以在匹配过程中避免重复匹配已经匹配过的字符,从而提高匹配效率。相比之下,朴素匹配没有使用额外的空间,但效率较低。
2024考研数据结构 文章被收录于专栏
本人考研刷算法题,立此专栏练习强化。