力扣 459. 重复的子字符串 使用KMP算法

力扣 459. 重复的子字符串 使用KMP算法

image.png

image.png

1、

这道题如果用暴力方法直接在原来的字符串里面找,时间复杂度是 O(n^2)。

2、

使用 KMP 算法求出 next 数组,通过 next 数组找到 next 数组的最后一个元素的值 next[n-1],如果这个字符串可以由它的一个重复子串重复多次构成,那么 next[n-1]必然不为 0, 并且字符串长度 n 减去 next[n-1] 的值可以整除 n,即 next[n-1]!=0 && n%(n-next[n-1])==0,我用的 next 数组是没有减 1 的版本。使用减去 1 的next数组,用来判断的表达式为 next[n-1]!=0 && n%(n-(next[n-1]+1))==0。

具体原理如下:s 的长度是 n,假设构成 s 的子串的长度是 x,m*x=n,m 是正整数,next数组的最后一个元素记录的是 s 的最长相等前后缀长度 y,n-y=x,问题转化为判断 m 是否为正整数,即判断 y!=0 && n%(n-y)==0 是否成立。

class Solution {
    public boolean repeatedSubstringPattern(String s) {
        int n=s.length();
        char[] chars=s.toCharArray();
        int[] next=new int[n];
        // 得到next数组
        for(int i=1, j=0; i<n; i++){
            while(j>0 && chars[i] != chars[j]){
                j=next[j-1];
            }
            if(chars[i]==chars[j]){
                ++j;
            }
            next[i]=j;
        }
        return next[n-1]!=0 && n%(n-next[n-1])==0;
    }
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注