刷题日记——KMP算法

28 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 29 天,点击查看活动详情

题目

28. 实现 strStr()

力扣题目链接(opens new window)

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1。

示例 1: 输入: haystack = "hello", needle = "ll" 输出: 2

示例 2: 输入: haystack = "aaaaa", needle = "bba" 输出: -1

说明: 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符.

KMP算法

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;
        }
    }

构造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;
    }
    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;
        }
    }
}

题目

459.重复的子字符串

力扣题目链接(opens new window)

给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。

示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。

示例 2:
输入: "aba"
输出: False

示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。

解法

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;
    }
}