代码随想录刷题随记8-KMP

代码随想录刷题随记8-KMP

KMP原理:文章链接

28. 找出字符串中第一个匹配项的下标

标准的kmp类型的题
leetcode链接

cpp 复制代码
class Solution {
public:
    
    vector<int> getnext(string s){
        if(s.size()==1){
            return {-1};
        }
        if(s.size()==2){
            return {-1,0};
        }
        vector<int>next=vector<int>(s.size(),0);
        next[0]=-1;
        next[1]=0;
        int cnt=0;
        int x=2;
        while(x<s.size()){
           if(s[x-1]==s[cnt]){
            next[x++]=++cnt;
           } 
           else if(cnt>0){
            cnt=next[cnt];
           }
          else{
           next[x++]=0;
          }
        }
        return next;
    }
    int strStr(string haystack, string needle) {
        if(needle.size()>haystack.size())
          return -1;
        vector<int> next=getnext(needle);
        int x=0;
         int y=0;
         while(x<haystack.size()&&y<needle.size()){
            if(haystack[x]==needle[y]){
                x++;
                y++;
            }
            else if(y>0){
                y=next[y];
            }
            else{
                x++;
            }
         }
         return  y==needle.size()? x-y:-1;
    }

};

459.重复的子字符串

leetcode 链接
方法1,暴力枚举

我们只需要判断,以第一个字母为开始的子串就可以,所以一个for循环获取子串的终止位置就行了。 而且遍历的时候 都不用遍历结束,只需要遍历到中间位置,因为子串结束位置大于中间位置的话,一定不能重复组成字符串。复杂度 O ( N 2 ) O(N^2) O(N2)

解题代码:

cpp 复制代码
class Solution {
public:
    bool repeatedSubstringPattern(string s) {
    for(int i=1;2*i<=s.size();i++){
        if(s.size()%i==0){
            bool match=true;
        for(int j=i;j<s.size();j++){
            if(s[j]!=s[j-i]){
              match=false;
              break;
            }
        }
        if(match)
          return match;
        }
       
    }
     return false;
    }
};

方法2

我们将两个 sss 连在一起,并移除第一个和最后一个字符。如果 sss 是该字符串的子串,那么 sss 就满足题目要求。

其中判断是否为字串采用kmp算法

解题代码:

cpp 复制代码
class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        return (s + s).find(s, 1) != s.size();
    }
};

方法三kmp

活用kmp的前后缀匹配思想

在由重复子串组成的字符串中,最长相等前后缀不包含的子串就是最小重复子串,这里拿字符串s:abababab 来举例,ab就是最小重复单位

数组长度减去最长相同前后缀的长度相当于是第一个周期的长度,也就是一个周期的长度,如果这个周期可以被整除,就说明整个数组就是这个周期的循环。

解题代码:

cpp 复制代码
class Solution {
public:
    vector<int> getnext(string s){
        if(s.size()==1){
            return {-1};
        }
        if(s.size()==2){
           return {-1 ,0};
        }
        vector<int> next=vector<int>(s.size()+1,0);
        next[0]=-1;
        next[1]=0;
        int x=2;
        int cnt=0;
        
        while(x<s.size()+1&&cnt<s.size()){
            if(s[x-1]==s[cnt]){
                next[x++]=++cnt;
            }
            else if(cnt>0){
                cnt=next[cnt];
            }
            else{
                next[x++]=0;
            }
        }
        return next;
    }
    bool repeatedSubstringPattern(string s) {
        if(s.size()<=1)
           return false;
           if(s.size()==2){
             return s[0]==s[1];
           }
        vector<int> next=getnext(s);
        int sublen=next[s.size()];
        int len=s.size();
        return (sublen!=0)&&(len%(len-sublen)==0)? true:false;
    }
};
相关推荐
自我意识的多元宇宙10 分钟前
树、森林——树与二叉树的应用(哈夫曼树的构造)
数据结构
|_⊙38 分钟前
C++ 智能指针
开发语言·c++
水蓝烟雨1 小时前
2071. 你可以安排的最多任务数目
数据结构·链表
Jasmine_llq1 小时前
《B4356 [GESP202506 二级] 数三角形》
开发语言·c++·双重循环枚举算法·顺序输入输出算法·去重枚举算法·整除判断算法·计数统计算法
山栀shanzhi1 小时前
在做直播时,I帧的间隔(GOP)一般是多少?
网络·c++·面试·ffmpeg
王老师青少年编程1 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【排序贪心】:魔法
c++·算法·贪心·csp·信奥赛·排序贪心·魔法
晓觉儿2 小时前
【GPLT】2026年第十一届团队程序设计天梯赛赛后题解(已写2h,存档中)
数据结构·c++·算法·深度优先·图论
6Hzlia2 小时前
【Hot 100 刷题计划】 LeetCode 394. 字符串解码 | C++ 单栈回压法
c++·算法·leetcode
流年如夢3 小时前
自定义类型进阶:联合与枚举
java·c语言·开发语言·数据结构·数据库·c++·算法
Little At Air3 小时前
C++stack模拟实现
linux·开发语言·c++·算法