leetcode-zgd-day10-459.重复的子字符串(KMP算法应用)

585 阅读2分钟

459.重复的子字符串

解题关键:

当一个字符串由重复子串组成的,最长相等前后缀不包含的子串就是最小重复子串。

关键就是对上面结论的证明。最后在判断剩余的这个最小重复子串的长度和字符串s的长度是否成倍数关系,不成倍数关系就代表整个字符串不是由重复的子字符串构成的。

论证就不具体展开了,参考相关博文:代码随想录 (programmercarl.com)

 class Solution {
     public boolean repeatedSubstringPattern(String s) {
         if(s.length() == 0) return false;
         // 计算出next数组
         int[] next = new int[s.length()];
         int j = 0;
         next[0] = 0;
         for(int i = 1; i < s.length(); i++){
             while(j > 0 && s.charAt(i) != s.charAt(j)){
                 j = next[j - 1];
             }
             if(s.charAt(i) == s.charAt(j)){
                 j++;
             }
             next[i] = j;
         }
         // 根据next数组的最后一位的值判断是否有重复的子字符串
         if(next[s.length() - 1] > 0 && s.length() % (s.length() - next[s.length() - 1]) == 0){
             return true;
         }
         return false;
     }
 }

方法2:移动匹配实现

关键点:

还是要先验证结论:将两个相同的字符串拼接在一起,如果在这个长字符串的中间能够组成一个新的拼接前的字符串,则代表这个字符串是由重复子字符串构成的。

论证就不具体展开了,参考相关博文:代码随想录 (programmercarl.com)

 class Solution {
     public boolean repeatedSubstringPattern(String s) {
         // 这种解法的关键就是拼接两个s,然后判断这个字符串中间还会不会出现拼接出来的s
         // 出现了就代表由重复子字符串构成,没出现就代表非重复子字符串构成
         StringBuilder ssb = new StringBuilder(s).append(s);
         String ss = ssb.substring(1, ssb.length() - 1).toString();
         // 掐头去尾
         // 还是得计算next数组
         int[] next = new int[s.length()];
         int j = 0;
         next[0] = 0;
         for(int i = 1; i < next.length; i++){
             while(j > 0 && s.charAt(i) != s.charAt(j)){
                 j = next[j - 1];
             }
             if(s.charAt(i) == s.charAt(j)){
                 j++;
             }
             next[i] = j;
         }
         // 根据next数组进行判断
         j = 0;
         for(int i = 0; i < ss.length(); i++){
             while(j > 0 && ss.charAt(i) != s.charAt(j)){
                 j = next[j - 1];
             }
             if(ss.charAt(i) == s.charAt(j)){
                 j++;
             }
             if(j == s.length()){
                 return true;
             }
         }
         return false;
     }
 }