459. 重复的子字符串

180 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第21天,点击查看活动详情

一、题目描述:

459. 重复的子字符串

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

示例 1:

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

示例 2:

输入: s = "aba"
输出: false

示例 3:

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

提示:

  • 1 <= s.length <= 10^4
  • s 由小写英文字母组成

二、思路分析:

主要是根据KMP算法的next数组特性(不了解KMP算法的读者也可以参考其他大佬的KMP算法讲解学习)

如果该字符串s可以由某个子串t重复n次表示,那么在next数组中最后一个元素的值应该是(s.legnth()-t.length()) 这个时候,我们只需要判断next数组的最后一个值next[s.length]是否能被(s.length()-next[s.length])整除即可(表示可以再用t重复n-1次表示) 当然也要排除一下next[s.length]=0的情况

三、AC 代码:

class Solution {
     public   int[] getNext(String s){//kmp求next数组
        int next[]=new int[s.length()+1];
        next[0]=-1;
        int k=-1,index=0;
        while(index<s.length()){
            if(k==-1||s.charAt(index)==s.charAt(k)){
                index++;
                k++;
                next[index]=k;
            }else{
                k=next[k];
            }
        }
        return next;
    }
    public boolean repeatedSubstringPattern(String s) {
        int[]next=getNext(s);
        int max=next[s.length()];
        if(max==0) return false;
        return max%(s.length()-max)==0;
    }
}


这道题需要我们先搞懂KMP的next数组是什么,如何构造。如果有这个知识点的话就很容易了。

参考:

基于最小表示法/最大后缀的时间复杂度O(n),空间复杂度O(1)的算法 - 重复的子字符串 - 力扣(LeetCode)

「代码随想录」带你搞定字符串!459. 重复的子字符串:【KMP经典问题】 - 重复的子字符串 - 力扣(LeetCode)