题目
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。
示例 2:
输入: "aba"
输出: False
示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)
题解
无官方题解
感想
先用素数判断的方法去试了一下,时间效率不行:
执行用时 : 291 ms, 在Repeated Substring Pattern的Java提交中击败了24.28%的用户
内存消耗 : 36.6 MB, 在Repeated Substring Pattern的Java提交中击败了98.68% 的用户
class Solution {
public boolean repeatedSubstringPattern(String s) {
int len = s.length();
if(len < 2) return false;
LinkedList<Integer> ll = primerList(len);
for(int primer: ll){
if(len%primer==0){
for(int i = 0;i<primer-1;i++){
if(!s.substring(i*len/primer,(i+1)*len/primer).equals(s.substring((i+1)*len/primer,(i+2)*len/primer))) break;
if(i==primer-2) return true;
}
}
}
return false;
}
private LinkedList<Integer> primerList(int n){
LinkedList<Integer> res = new LinkedList<>();
if(n<2) return res;
res.add(2);
if(n==2) return res;
for(int i = 3; i<=n;i+=2){
boolean flag = true;
for(int primer:res){
if(i%primer==0) {flag= false;break;}
}
if(flag == true) res.add(i);
}
return res;
}
}
后来参考评论区有一种做法:先s+s合并两个字符串以后,在除了一开始的两个s字符串位置可以查到s之外,如果s存在重复子字符串,一定能够再找到其他的s。利用这个性质就可以得出一个很简洁的方法:
执行用时 : 65 ms, 在Repeated Substring Pattern的Java提交中击败了51.31%的用户
内存消耗 : 46.7 MB, 在Repeated Substring Pattern的Java提交中击败了78.57% 的用户
class Solution {
public boolean repeatedSubstringPattern(String s) {
if(s.length()<2) return false;
String twoS = s+s;
return twoS.substring(1,twoS.length()-1).contains(s);
}
}
貌似还有更快的方法,不知道怎么搞得。