459. 重复的子字符串-KMP算法

459. 重复的子字符串

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

示例 1:

输入: s = “abab”
输出: true
解释: 可由子串 “ab” 重复两次构成。

示例 2:

输入: s = “aba”
输出: false

示例 3:

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

思考

如果字符串s是由多个子串重复组成,那么该字符串s最长相等的前缀后缀为组成该字符串s 的子串!

  • 其实就是字符串s 最后一位的next数组值 即为子串长度
字符串s a b b a b b
next[i] 0 0 0 1 2 3

举例:abbabbnext[5]=3

如果该字符串为多个子串组成那么子串为s[0...2]

  • 求字符串的next数组参考构造next数组
    • 初始化前缀指针j,后缀指针i,next[0]=0
    • 前后缀指针对应值相同时
    • 前后缀指针对应值不同时

该题属于KMP算法
可以参考我的另一篇文章KMP算法进行理解

package 力扣;

/**
 * @author yyq
 * @create 2022-03-26 21:02
 */
public class leetcode459 {
    public static void main(String[] args) {
        System.out.println(repeatedSubstringPattern("babbab"));
    }
    public static boolean repeatedSubstringPattern(String s) {
        if(s.length()==1) return true;
        // 1.初始化
        int j = 0; //前缀指针
        int i = 1; //后缀指针
        int[] next=new int[s.length()];
        char[] chars = s.toCharArray();
        // 开始逐步求出每个子串 chars[0 - i] 的最大相等前后缀的长度
        while (i<chars.length){
            // 前后缀指针值相等
            if(chars[j] == chars[i]){
                // 子串chars[0 - i] 的最大相等前后缀的长度 为前缀长度
                next[i] = j + 1;
                i++;
                j++;
            }
            // 前后缀指针值不相等
            else {
                // **** j $%&^( ****i
                // 此时需要回退 j 
                while (j!=0&&chars[j]!=chars[i]){
                    j=next[j-1];
                }
                if(j==0){
                    if(chars[j]==chars[i]){
                        next[i]=1;
                        j++;
                        i++;
                    }else {
                        next[i]=0;
                        i++;
                    }
                }else {
                    next[i] = j + 1;
                    j++;
                    i++;
                }
            }
        }
        int l=next[chars.length-1];
        
        // 如果该字符串没有前后缀相等 肯定不是由子串组成了
        if(l==0) return false;
        for (int a = l;a<chars.length;a++){
            if(chars[a]!=chars[a-l]) return false;
        }
        return true;
    }
}

你可能感兴趣的:(LeetCode,#,字符串,leetcode,java,算法)