算法训练营day9

文章介绍了如何使用KMP算法来找到字符串中的第一个匹配项的下标,以及检查一个字符串是否由重复的子串组成。通过对原字符串和目标子串的预处理,构建next数组,然后遍历以判断匹配情况。在第二个问题中,通过将字符串自身拼接并搜索子串来判断是否存在重复的子串模式。
摘要由CSDN通过智能技术生成

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

思路

这里用kmp,复习一下;
1.把两个串拼接起来,前半部分是短串,后半部分是长串,中间加个“#”,一个循环搞定,前半部分预处理next数组,后半部分直接查表,后半部分的next相当于f了;
2.从m+2开始遍历,看能找到匹配的不,注意我的下标是从1开始,还有就是要减去前面的m+1(前半部分数组大小m以及"#'大小为1);

int nxt[20010];
class Solution {
public:
    int strStr(string haystack, string needle) {
        int n=haystack.size(),m=needle.size();
        needle=" "+needle;
        needle+="#";
        needle+=haystack;

        int j=0;
        nxt[1]=0;
        for(int i=2;i<=n+m+1;i++){
            while(j>0&&needle[j+1]!=needle[i])
                j=nxt[j];
            if(needle[j+1]==needle[i]) j++;
            nxt[i]=j;
        }

        int ans=-1;
        for(int i=m+2;i<=n+m+1;i++){
            if(nxt[i]==m){
                ans=i-m+1-m-1-1;
                break;
            }
        }
        return ans;
    }
};

459.重复的子字符串

思路

随想录里的思路挺妙的;
1.一个字符串如果可以由子串拼接而成,假设当前字符串由AB组成,那么BA一定也可以组成字符串;
2.这里往后面再拼一个当前字符串构成新的字符串t,判断原字符串s是否为t的子串;
3.注意t要刨头去尾,保证搜出来的是中间拼接出来的s;

int nxt[30010];
class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        string t=s+s;
        t.erase(t.begin());
        t.erase(t.end()-1);

        int n=t.size(),m=s.size();
        s=" "+s;
        s+="#";
        s+=t;

        int j=0;
        nxt[1]=0;
        for(int i=2;i<=n+m+1;i++){
            while(j>0&&s[j+1]!=s[i])
                j=nxt[j];
            if(s[j+1]==s[i]) j++;
            nxt[i]=j;
        }

        for(int i=m+2;i<=n+m+1;i++){
            if(nxt[i]==m) return true;
        }
        return false;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值