代码随想录算法训练营第九天 | 28、459

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

题目介绍

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。
示例1:
输入: h a y s t a c k = " s a d b u t s a d " , n e e d l e = " s a d " haystack = "sadbutsad", needle = "sad" haystack="sadbutsad",needle="sad"
输出: 0 0 0
示例2:
输入: h a y s t a c k = " l e e t c o d e " , n e e d l e = " l e e t o " haystack = "leetcode", needle = "leeto" haystack="leetcode",needle="leeto"
输出: − 1 -1 1

思路

能看出来是KMP的题,但是KMP不会写,真的会裂开。直接上答案叭,KMP还是需要再练练。

解法

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;
    }
    public void getNext(int[] next,String s){
        int j = 0;
        next[0] = 0;
        for(int i=1;i<s.length();i++){
            while(j>0 && s.charAt(j) != s.charAt(i)){
                j = next[j-1];
            }
            if(s.charAt(j) == s.charAt(i)){
                j++;
            }
            next[i] = j;
        }
    }
}

总结

没啥可总结的,总结就是,需要熟练掌握KMP,回去再练练。

459. 重复的子字符串

题目介绍

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
示例1:
输入: s = " a b a b " s = "abab" s="abab"
输出: t r u e true true
示例2:
输入: s = " a b a " s = "aba" s="aba"
输出: f a l s e false false
示例3:
输入: s = " a b c a b c a b c a b c " s = "abcabcabcabc" s="abcabcabcabc"
输出: t r u e true true

思路

可以想见若两个s相连在一起,那么如果要返回true,则中间必须在拼接后要能出现至少第三个s。而这一点的判断可以经由相同的前后缀来判断。

解法

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        if(s.equals("")) return false;
        int len = s.length();
        s = " "+s;
        char[] chars = s.toCharArray();
        int[] next = new int[len+1];
        for(int i = 2,j = 0;i<=len;i++){
            while(j>0 && chars[i] != chars[j+1]) j = next[j];
            if(chars[i] == chars[j+1]) j++;
            next[i] = j;
        }
        if(next[len] >0 && len%(len-next[len]) == 0){
            return true;
        }
        return false;
    }
}

总结

很巧妙的一道题,但我觉得我还是要再重新看看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值