1.在牛客网上遇到的KMP算法
题目描述
给你一个字符串S和T
计算S在T出现了多少次?
数据范围:1<=len(S)<=5∗1e5,1<=len(T)<=1e6
复杂度要求:O(m*n)
示例1
输入:"ababab","abababab"
输出: 2
示例12
输入:"abab","abacabab"
输出: 1
C++解答
思路
这题跟leetcode上一条str比较相似,不同的是:S在T中可能出现多次,因此需要每次匹配出结果后,需要对数组进行一次回退,其余跟str一致。
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 计算模板串S在文本串T中出现了多少次
* @param S string字符串 模板串
* @param T string字符串 文本串
* @return int整型
*/
vector<int> next_arr(string& str){
int n = str.size();
vector<int> next(n, 0);
int j = 0;
for(int i = 1; i < n; i++){
while(j > 0 && str[i] != str[j]){
j = next[j - 1];
}
if(str[i] == str[j])
j++;
next[i] = j;
}
return next;
}
int kmp(string S, string T) {
// write code here
int m = S.size(), n = T.size();
if(m > n) return 0;
int count = 0;
vector<int> next = next_arr(S);
int j = 0;
for(int i = 0; i < n; i++){
while(j > 0 && S[j] != T[i]){
j = next[j - 1];
}
if(S[j] == T[i])
j++;
//匹配到m时选择回退还是跳出循环,必须是j == m,因为上次匹配的是j - 1
if(j == m){
//如果P也到头了,跳出循环
if(i == n - 1){
count++;
break;
}
j = next[j - 1];
count++;
}
}
return count;
}
};

浙公网安备 33010602011771号