代码随想录刷题随记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;
    }
};
相关推荐
薯条不要番茄酱13 分钟前
数据结构-8.Java. 七大排序算法(中篇)
java·开发语言·数据结构·后端·算法·排序算法·intellij-idea
是阿建吖!19 分钟前
【优选算法】二分查找
c++·算法
Ajiang28247353042 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
盼海2 小时前
排序算法(五)--归并排序
数据结构·算法·排序算法
‘’林花谢了春红‘’7 小时前
C++ list (链表)容器
c++·链表·list
搬砖的小码农_Sky8 小时前
C语言:数组
c语言·数据结构
机器视觉知识推荐、就业指导9 小时前
C++设计模式:建造者模式(Builder) 房屋建造案例
c++
先鱼鲨生10 小时前
数据结构——栈、队列
数据结构
一念之坤10 小时前
零基础学Python之数据结构 -- 01篇
数据结构·python