459. 重复的子字符串

题目:

给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。

示例 2:
输入: "aba"
输出: False

示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-substring-pattern

法1:周期性

 1  1 /*周期串为s,那么设定t表示周期,那么剩下的就是依次对每个t值进行遍历看是否真的满足周期为t,数学中周期的表达式是f(x+t)==f(x),那么代码中可以这样写s[i%t]==s[i]*/
 2  2 
 3  3 class Solution {
 4  4     public boolean repeatedSubstringPattern(String s) {
 5  5         //如果真的具有周期性,t>=1,t <= s.length/2
 6  6         if(s == null) return false;
 7  7         for(int t = 1; t <= s.length()/2; t++){  //为所有可能的周期长度,即题目中的子串长度
 8  8             if(s.length() % t != 0) continue;    //s如果具有周期性,它和子串在长度上成倍数关系,直接减少一些判断
 9  9             int i = t;
10 10             while( i < s.length() && s.charAt(i % t) == s.charAt(i)){ //判断是否满足f(x+t)==f(x)
11 11                 i++;
12 12             }
13 13             if(i == s.length()) return true;
14 14         }
15 15         return false;
16 16         
17 17     }
18 18 }

法2:split()活用

split(String str) 的一般情况:

459. 重复的子字符串_第1张图片

 

 特殊情况:

如果字符串与输入的任何一部分都不匹配,得到的字符串数组将只有一个元素,即这个字符串。

如果输入的是字符串的周期性子串,得到的字符串数组长度为0。

 1 // 法二:活用split()
 2 // 如果字符串存在周期性,那么以该子串分割字符串得到的字符串数组应该长度为0
 3 //不能忽视这里隐含的条件:字符串的长度是子串的整数倍(筛选,减少时间)
 4 class Solution {
 5     public boolean repeatedSubstringPattern(String s) {
 6         if(s == null) return false;
 7         for(int t = s.length()-1; t > 0; i--){ //t为子串长度
 8             if(s.length() % t != 0) continue;
 9             if(s.split(s.substring(0,t)).length == 0)  return true;
10         }
11         return false;
12     }
13 }

法3:

拼接该字符串,截去首尾各一个字符,如果仍然包含该字符串则包含重复的子字符串(具有周期性)。只截一个是为了判断重复子串长度为1的情况。当重复子串长度大于1时,任意截去首尾小于等于重复子字符串长度都可

1 class Solution {
2     public boolean repeatedSubstringPattern(String s) {
3         String str = s+s;
4         str = str.substring(1,str.length()-1);
5         return str.contains(s);
6     }
7 }

 

你可能感兴趣的:(459. 重复的子字符串)