代码随想录算法训练营Day09:28.实现strStr(),459.重复的子字符串

这两题需要巩固!!!

28.实现strStr()

文章链接:代码随想录 (programmercarl.com)

思路:使用KMP算法,因为是要判断子字符串是否在另一个字符串中出现过,KMP算法还需要定义获取子字符串的Next数组

Java代码:

class Solution {
    public int strStr(String haystack, String needle) {
        //使用KMP算法
        int indexhay = 0;
        int indexnee = 0;
        //计算需要获取needle的next数组
        int[] needleNext = getNextarray(needle);
        //开始遍历比较
        while(indexhay < haystack.length() && indexnee < needle.length()){
            //两个字符串字符相等的情况
            if(haystack.charAt(indexhay) == needle.charAt(indexnee)){
                indexhay++;
                indexnee++;
            }
            //没匹配上的情况如下
            //如果此时indexnee大于0,表示可以通过next数组重新定位indexnee
            else if(indexnee > 0){
                //找到新的indexnee位置在跟indexhay处的字符进行比较
                indexnee = needleNext[indexnee];
            }
            //indexnee比0小了,不能再调用next数组了
            else{
                indexhay++;
            }
        }
        //如果此时indexnee在遍历完最后一个字符时,再++
        return indexnee == needle.length()? indexhay - indexnee : -1;
    }

    //定义获取next数组的函数
    private int[] getNextarray(String s){
        if(s.length() == 1){
            return new int[] {-1};
        }
        int[] next = new int[s.length()];
        next[0] = -1;//人为规定
        next[1] = 0;//人为规定
        int i = 2;//所以要从i = 2开始
        int cn = 0;//cn代表两个意思
        while(i < s.length()){
            if(s.charAt(i - 1) == s.charAt(cn)){
                next[i] = cn + 1;
                i++;
                cn++;
            }
            else if(cn > 0){
                cn = next[cn];
            }
            else{
                next[i] = 0;
                i++;
            }
        }
        return next;
    }
}

459.重复的子字符串

文章链接:代码随想录 (programmercarl.com)

思路:想到了使用移动匹配,但不知道具体操作流程是什么。

看完文章后的反思:

(1)移动匹配:用 s + s,这样组成的字符串中,后面的子串做前串,前后的子串做后串,就一定还能组成一个s;

所以判断字符串s是否由重复子串组成,只要两个s拼接在一起,里面还出现一个s的话,就说明是由重复子串组成;

当然,我们在判断 s + s 拼接的字符串里是否出现一个s的的时候,要刨除 s + s 的首字符和尾字符,这样避免在s+s中搜索出原来的s,我们要搜索的是中间拼接出来的s。

Java移动匹配代码:

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        if(s.length() == 0 || s.equals("")){
            return false;
        }
        //使用移动匹配的方法
        String news = s + s;
        StringBuilder sb = new StringBuilder();
        //要刨除news的首尾字符,要搜索中间是否出现s
        for(int i = 1; i < news.length() - 1;i++){
            sb.append(news.charAt(i));
        }
        //在sb中搜索是否存在s,运用StringBuilder的方法indexOf:返回第一个匹配的索引
        return sb.indexOf(s) >= 0 ? true:false;
    }
}

算法小白还需继续努力!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值