刷题时偶然遇到一个字符串匹配问题,正好之前 KMP 算法没搞很清楚,所以记录一下经典问题:(因为符号太多了,所以后面直接截图省事
题解
算法的核心为前缀函数,记作 ,其定义如下:
对于长度为 m 的字符串 s ,其前缀函数表示 s 的子串 s[0:i] 的最长的相等的真前缀与真后缀的长度。特别地,如果不存在符合条件的前后缀,那么 ,其中真前缀与真后缀的定义为不等于自身的前缀与后缀。

如何求解前缀函数
长度为 m 的字符串 s 的所有前缀函数的求解算法的总时间复杂度是严格 O(m) 的,且该求解算法是增量算法,即我们可以一边读入字符串,一边求解当前读入位的前缀函数。
为了叙述方便,我们接下来将说明几个前缀函数的性质:




class Solution {public:int strStr(string haystack, string needle) {int n = haystack.size(), m = needle.size();if (m == 0) {return 0;}vector<int> pi(m);for (int i = 1, j = 0; i < m; i++) {while (j > 0 && needle[i] != needle[j]) {j = pi[j - 1];}if (needle[i] == needle[j]) {j++;}pi[i] = j;}for (int i = 0, j = 0; i < n; i++) {while (j > 0 && haystack[i] != needle[j]) {j = pi[j - 1];}if (haystack[i] == needle[j]) {j++;}if (j == m) {return i - m + 1;}}return -1;}};// 作者:LeetCode-Solution// 链接:https://leetcode-cn.com/problems/implement-strstr/solution/shi-xian-strstr-by-leetcode-solution-ds6y/// 来源:力扣(LeetCode)// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
