LeetCode28. 实现 strStr()

题目

分析

经典的一道字符串匹配题目,有两种方法,朴素的暴力和KMP算法

这里不仅要能熟练写出朴素算法也要会写KMP算法

KMP算法推荐 y 总的模板,如下:

我们一般字符串从1开始,所以一开始加个空字符

// s[]是长文本,p[]是模式串,n是s的长度,m是p的长度
求模式串的Next数组:
for (int i = 2, j = 0; i <= m; i ++ )  //从2开始,1本身就是平凡的,前后缀相同,ne[1] = 0不用求了
{
    while (j && p[i] != p[j + 1]) j = ne[j];
    if (p[i] == p[j + 1]) j ++ ;
    ne[i] = j;
}

// 匹配
for (int i = 1, j = 0; i <= n; i ++ )
{
    while (j && s[i] != p[j + 1]) j = ne[j];
    if (s[i] == p[j + 1]) j ++ ;
    if (j == m)
    {
        j = ne[j];
        // 匹配成功后的逻辑
    }
}

 

 

 

代码

朴素算法

时间复杂度O(m * n)

 1 class Solution {
 2 public:
 3     int strStr(string h, string n) {
 4         if(n.empty() || h.empty()) return 0;
 5 
 6         int i = 0,j = 0;
 7         
 8         while(i < h.size() && j < n.size()){
 9            if(h[i] == n[j]) i++,j++;
10            else{
11                i = i - j + 1; // 回退
12                j = 0;
13            }
14         }
15 
16         if(j == n.size()){
17             return i - j;
18         }else {
19             return -1;
20         }
21     }
22 };

KMP算法

时间复杂度O(n + m )

 1 class Solution {
 2 public:
 3     int strStr(string s, string p) {
 4         if(!p.size()) return 0;
 5         int n = s.size(), m = p.size();
 6         s = ' ' + s;
 7         p = ' ' + p;
 8 
 9         vector<int>next(m+1);
10 
11         //首先先求next数组,其实相当于两个p串匹配
12         for(int i = 2,j = 0;i <= m;i++){ //从2开始next[1]为0,i 要小于等于m
13             while(j && p[i] != p[j+1]) j = next[j];
14             if(p[i] == p[j+1]) j++;
15             next[i] = j;
16         }
17 
18         //然后求s,p匹配
19         for(int i = 1,j = 0;i <= n;i++){
20             while(j && s[i] != p[j+1]) j = next[j];
21             if(s[i] == p[j+1]) j++;
22             if(j == m) return i - m;
23         }
24 
25         return -1;
26     }
27 };

 

posted @ 2022-04-07 23:11  Uitachi  阅读(19)  评论(0编辑  收藏  举报