跳转至

459. 重复的子字符串

题目描述

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

 

示例 1:

输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。

示例 2:

输入: s = "aba"
输出: false

示例 3:

输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)

 

提示:

  • 1 <= s.length <= 104
  • s 由小写英文字母组成

解法

方法一:双倍字符串

若长度为 \(n\) 的字符串 \(s\)\(m\) 个重复子串组成,将 \(s\) 拼接在自身上,得到字符串 \(ss\),长度为 \(2n\),此时若从下标 \(1\) 开始查找 \(s\),那么查找到的下标一定小于 \(s\) 的长度。

若长度为 \(n\) 的字符串 \(s\) 不由重复子串组成,将 \(s\) 拼接在自身上,得到字符串 \(ss\),长度为 \(2n\),此时若从下标 \(1\) 开始查找 \(s\),那么查找到的下标一定等于 \(s\) 的长度。

时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)。其中 \(n\) 为字符串 \(s\) 的长度。

1
2
3
class Solution:
    def repeatedSubstringPattern(self, s: str) -> bool:
        return (s + s).index(s, 1) < len(s)
1
2
3
4
5
6
class Solution {
    public boolean repeatedSubstringPattern(String s) {
        String str = s + s;
        return str.substring(1, str.length() - 1).contains(s);
    }
}
1
2
3
4
5
6
class Solution {
public:
    bool repeatedSubstringPattern(string s) {
        return (s + s).find(s, 1) < s.size();
    }
};
1
2
3
func repeatedSubstringPattern(s string) bool {
    return strings.Index(s[1:]+s, s) < len(s)-1
}
1
2
3
function repeatedSubstringPattern(s: string): boolean {
    return (s + s).slice(1, (s.length << 1) - 1).includes(s);
}
1
2
3
4
5
impl Solution {
    pub fn repeated_substring_pattern(s: String) -> bool {
        (s.clone() + &s)[1..s.len() * 2 - 1].contains(&s)
    }
}

评论