KMP算法--459题

zhanglei 2022年05月31日 261次浏览

题目

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

 

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

示例 2:
输入: s = "aba"
输出: false

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

个人解答(前缀表不减1)

class Solution {
    public boolean repeatedSubstringPattern(String s) {
         if (s.length() == 0) {
            return false;
        }
         int[] next = new int[s.length()];
         int len = s.length();

         //获取模式串的前缀表
        getNext(next,s);

         // 最后判断是否是重复的子字符串,这里 next[len-1] 即代表next数组末尾的值。
         //这里len - next[len-1])就是一个周期的长度。
         //如果整个长度能整除周期长度,那么说明是重复的子串构成的。
        if (next[len-1] > 0 && len % (len - next[len-1]) == 0) {
            return true;
        }
        return false;

    }
		//确定前缀表的每一个数值
    private 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; 
            }
        }
}

个人总结

第一次看到这个题目实在carl哥的代码随想录里面,第一次看KMP算法的文字解释根本看不懂,后面看了b站上carl哥的视频才对前缀表以及前缀表的作用有了那么一丢丢感觉!!做了两道题之后,总结出如下规律:
1.KMP算法用于字符串匹配上,也就是说出现字符串匹配就可以想到KMP算法
2.KMP实现的步骤
先构造一个方法getNext(int[] next,String s),设置next数组的每一个元素
然后写匹配过程(有无此过程看实际情况),先找到第一次匹配的位置,用while语句,里面语句是j=next[j-1];
跳出while语句后,再做判断,如果匹配,那么j后移动;
最后根据不同需求做不同的判断,按需求返回不同的值。

总之KMP算法真的太难了!!我被折磨的不轻,真佩服Knuth,Morris,Pratt三位大佬!

不多说了,好好学习吧!!