给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: "abab"
输出: True
解释: 可由子字符串 "ab" 重复两次构成。
示例 2:
输入: "aba"
输出: False
示例 3:
输入: "abcabcabcabc"
输出: True
解释: 可由子字符串 "abc" 重复四次构成。 (或者子字符串 "abcabc" 重复两次构成。)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-substring-pattern
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法一:
对于一个常为 n n nd的字符串,假设他了一由长度为 n ′ n' n′的子串 s ′ s' s′重复多次构成,那么:
- n n n一定是 n ′ n' n′的倍数;
- 那么一定有等式 s [ i ] = s [ i − n ′ ] s[i]=s[i-n'] s[i]=s[i−n′]成立。
因此我们可以枚举 n ′ n' n′的大小,这里的 n ′ n' n′不会大于 n n n的一半。
复杂度: O ( n 2 ) O(n^2) O(n2), O ( 1 ) O(1) O(1)。
代码
class Solution {
public:
bool repeatedSubstringPattern(string s) {
int n = s.size();
for(int i=1; i*2<=n; ++i)
{
if(n%i==0)
{
bool match = true;
for(int j=i; j<n; ++j)
{
if(s[j]!=s[j-i])
{
match = false;
break;
}
}
if(match)
return true;
}
}
return false;
}
};
方法二:字符串匹配
可以把字符串
s
s
s写成
s
′
s
′
.
.
.
s
′
s
′
s's'...s's'
s′s′...s′s′
如果我们将一
s
′
s'
s′从字符串头部移到尾部他应该不变。如果我们将两个
s
s
s连在一起,去掉头部的一个字符和尾部的一个字符如果,其子串中包含
s
s
s,那么就是满足题目要求的。
复杂度: 查找时用KMP算法时间复杂度 O ( n ) O(n) O(n)
在下面的代码中,我们可以从位置 11 开始查询,并希望查询结果不为位置 n n n,这与移除字符串的第一个和最后一个字符是等价的。
class Solution {
public:
bool repeatedSubstringPattern(string s) {
return (s + s).find(s, 1) != s.size();
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/repeated-substring-pattern/solution/zhong-fu-de-zi-zi-fu-chuan-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。