代码随想录刷题随记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;
    }
};
相关推荐
我是谁??32 分钟前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
南宫生1 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
发霉的闲鱼1 小时前
MFC 重写了listControl类(类名为A),并把双击事件的处理函数定义在A中,主窗口如何接收表格是否被双击
c++·mfc
小c君tt1 小时前
MFC中Excel的导入以及使用步骤
c++·excel·mfc
xiaoxiao涛1 小时前
协程6 --- HOOK
c++·协程
weixin_432702262 小时前
代码随想录算法训练营第五十五天|图论理论基础
数据结构·python·算法·深度优先·图论
passer__jw7673 小时前
【LeetCode】【算法】283. 移动零
数据结构·算法·leetcode
爱吃生蚝的于勒3 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~3 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
脉牛杂德4 小时前
多项式加法——C语言
数据结构·c++·算法