题目(leecode T28):
给你两个字符串 haystack
和 needle
,请你在 haystack
字符串中找出 needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle
不是 haystack
的一部分,则返回 -1
。
方法:KMP算法
KMP算是是字符串匹配问题的常用方法,他解决的是暴力匹配所带来的时间复杂度极高的弊端。当我们在暴力匹配字符串时,如果模式串和文本串不匹配时,我们需要从下一个文本串的字符开始从头匹配模式串,但KMP算法引入了一个next数组来解决这个问题。next数组中存放的是模式串的最长相等前后缀,它可以告诉模式串在当前位置匹配不成功后的下一个匹配的位置在哪,其实这个位置就是模式串的最长的公共前后缀中最大的位置,从该位置继续匹配
class Solution {
public:void getNext(int* next, const string& s) { //计算next数组int j = 0;next[0] = 0;for(int i = 1; i < s.size(); i++) { //遍历字符串s吗,求其最长相等前后缀while (j > 0 && s[i] != s[j]) {j = next[j - 1];}if (s[i] == s[j]) {j++;}next[i] = j;}}int strStr(string haystack, string needle) {if (needle.size() == 0) { //定义如果模式串为空则返回0return 0;}vector<int> next(needle.size());getNext(&next[0], needle);int j = 0;for (int i = 0; i < haystack.size(); i++) {while(j > 0 && haystack[i] != needle[j]) {j = next[j - 1];}if (haystack[i] == needle[j]) {j++;}if (j == needle.size() ) {return (i - needle.size() + 1);}}return -1;}
};