代码随想录Day09实现strStr() 重复的子字符串

代码随想录Day09|实现strStr() 重复的子字符串

1.题目链接:找出字符串中第一个匹配项的下标 - 力扣

题目描述:给你两个字符串 haystackneedle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1

示例 1:

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。

示例 2:

输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。

文章讲解/视频讲解:https://programmercarl.com/0028.%E5%AE%9E%E7%8E%B0strStr.html

解题思路:

暴力解法,使用两个for循环,一个个向后进行比较。直到找到对应的字符串,循环结束,仍未找到相应的字符串,则返回-1

下面是代码示例:

class Solution {
    public int strStr(String haystack, String needle) {
        for(int i=0;i<=haystack.length()-needle.length();i++){
            int k=i;
            int j=0;
            while(j<needle.length()&&haystack.charAt(k)==needle.charAt(j)){
                k++;
                j++;
            }
            if(j==needle.length()){
                return i;
            }
        }
        return -1;
    }
}

KMP算法,相较于暴力解法,KMP算法可以避免重头匹配。当出现字符串不匹配的时候,可以知道前面一部分已经匹配了的内容,这样可以避免从头再去做匹配了。

KMP算法需要我们知道子字符串的next值,求next数组,则是需要自己与自己进行比较,算出next值。很容易得知next数组的第一个数值一定是0,我们可以让i=1,然后j=0,进行比较。字母相同则一起往后++,若字母不相同,j就要等于它前一个字母所对应的next值。循环结束,最后求出子字符串对应的next值。

利用子字符串的next值,以及上面的求解方法,也很容易写出匹配的子字符串。

下面试代码示例:

class Solution{
    public int strStr(String haystack, String needle){
        if(needle.length()==0) return 0;
        int[] next=new int[needle.length()];
        getNext(next,needle);

        int j=0;
        for(int i=0;i<haystack.length();i++){
            while(j>0&&needle.charAt(j)!=haystack.charAt(i)) j=next[j-1];
            if(needle.charAt(j)==haystack.charAt(i)) j++;
            if(j==needle.length())
                return i-needle.length()+1;
        }
        return -1;
    }
//next数组找到相对应的值
    public void getNext(int[] next, String s){
        int j=0;
        next[0]=0;
        for(int i=1;i<s.length();i++){
            //字符不匹配的情况,j进行回退
            while(j>0&&s.charAt(i)!=s.charAt(j)) j=next[j-1];
            if(s.charAt(i)==s.charAt(j)) j++;
            next[i]=j;
        }
    }
}

2.题目链接:重复的子字符串 - 力扣

题目描述:给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

示例 1:

输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。

示例 2:

输入: s = "aba"
输出: false

示例 3:

输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)

文章讲解/视频讲解:https://programmercarl.com/0459.%E9%87%8D%E5%A4%8D%E7%9A%84%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2.html

解题思路

使用移动匹配的方式。当一个字符串s:abcabc,那它一定是由前后相同的字符串组成的。既然有前面有相同的字符串,后面有相同的字符串,那么我们可以ss=s+s组成一个这样字符串,第一个s的后面的子串做前面的字符串,第二个前面的子串做后面的字符串。然后把ss的头和尾去掉,寻找新的字符串能不能够组成新的字符串s,如果可以组成,那么说明这个s就是由重复的子字符串组成的。

下面是代码示例:

class Solution{
    public boolean repeatedSubstringPattern(String s) {
        String ss=s+s;
        return ss.substring(1,ss.length()-1).contains(s);
    }
}

总结:

今天写的题目比较少,KMP算法在上一年学习过,但是只记得七七八八,还不太会应用。对于计算next的已经会了,但大概的思路还是不能够很清晰的说出来,还是需要多下点功夫,后续补充在评论区(希望自己不是在给自己画饼)算法还是需要偶尔去回顾和学习。第二题关于使用KMP算法的方法还没有完全掌握,周末没有课的时候还需要多看看。今天又了解了一些String字符串的使用方法,还是需要多学多记。

  • 36
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值