🍀 重复的子字符串
描述:
# 给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。
示例 2:
输入: s = "aba"
输出: false
示例 3:
输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
提示:
1 <= s.length <= 104
s 由小写英文字母组成
思考:
由题意得判断该字符串是否有重复的字串,也就是说即保证有重复的字串,也得保证除了重复字串没有其它多余的字符。
如"abcabc",往左移动一位"bcabca",再移动两位"abcabc",字符串恢复到原位了,假设字符串长为n,则设重复字符串最多有两串,也就是单个不重复字符串长最长为n/2。这种方法类似于滑动窗口的方法,通过滑动单个最长字符长度,如果是题中要求的字符串就会与原字符串重合,问题也就简化成移动匹配问题了,移动位数最大为n/2!
那移动窗口应该怎样实现呢...........对了!java对字符串提供了很多的方法,可以通过字符串拼接来实现!就是不知道会不会一会提交会不会超时?
ok,暂且先这样想,实现一下试试!
实现:
class Solution {
public boolean repeatedSubstringPattern(String s) {
if(s == null)
return false;
int n = s.length();
int sign = n/2;
String s1 = s;
while(n > sign){
// 相当于滑动一个字符的效果,把最后一个字符添加到最开始,再截断最后一个字符。
// 做一个拼接,好像有点太蠢了。。。
s1 = s1.charAt(s.length() - 1) + s1.substring(0, s.length() - 1);
if(s1.equals(s))
return true;
n--;
}
return false;
}
}
测试一下!
通过128种,错了一个!单个字符有bug!如果是单个字符确实可以通过测试!加判断!
class Solution {
public boolean repeatedSubstringPattern(String s) {
if(s == null)
return false;
int n = s.length();
if(n == 1)
return false;
int sign = n/2;
String s1 = s;
while(n > sign){
// 相当于滑动一个字符的效果,把最后一个字符添加到最开始,再截断最后一个字符。
// 做一个拼接,好像有点太蠢了。。。
s1 = s1.charAt(s.length() - 1) + s1.substring(0, s.length() - 1);
if(s1.equals(s))
return true;
n--;
}
return false;
}
}
解法成功!不过效率真的好低能= =
看看大佬是如何实现的!
大佬的代码!!!
class Solution {
public boolean repeatedSubstringPattern(String s) {
String str = s + s;
return str.substring(1, str.length() - 1).contains(s);
}
}
短短两行代码就解决了,大佬的思想和我刚开始想的一样,但是代码实现也比我简单很多很多。简而言之就是:如果是符合题意的字符串,两倍的字符串,切割掉收尾(相当于滑动任意位数的结果),其内部必定含有原字符串!
大佬思想链接:leetcode-cn.com/problems/re…