Repeated Substring Pattern
Given a non-empty string check if it can be constructed by taking a
substring of it and appending multiple copies of the substring
together. You may assume the given string consists of lowercase
English letters only and its length will not exceed 10000.Example:
Input: "abab" Output: True
Explanation: It's the substring "ab" twice.
给定一个字符串,判断该字符串能否由其自身的某一个子串通过不断重复而得到。
暴力法
复杂度
时间 O(N^2) 空间O(1)
思路
如果一个字符串s能够通过其某一子串不断重复而得到,那么这个子串的开头肯定是这个字符串s的开头。如果要符合题目条件,子串至少要重复2次(比如abcabc
),而至多可以重复字符串s的长度那么多次(比如aaaaa
)。我们穷举所有可能的倍数,一一测试,就能得到是否存在这么一个子串,通过不断重复而得到母串s。
class Solution:
def repeatedSubstringPattern(self, s):
"""
:type s: str
:rtype: bool
"""
if len(s) <= 1:
return False
length = len(s)
for times in range(2, len(s) + 1): # 最少重复2次,最多重复length次
if length % times == 0 and times * s[0:length//times] == s: # 复制times次数,看是否和母串相同
return True
return False
双倍法
复杂度
时间 O(N) 空间O(1)
思路
这种解法其实类似于数学题,假设字符串S由k个字符串a组成,那么如果将两个字符串S相连成为2S时,其中必定出现了2k次字符串a。由于k必定大于等于2(如果k=1,那a就是S了,不成立),那么在2k个字符串a的中间部分肯定能找到k个字符串a,而k个字符串a就是字符串s(比如k=2时,2S = aaaa = aSa
),为了避免拿到前面和后面的k个字符串a(k=2时,避免类似于Saa
和aaS
的情况),我们将2S的首尾字母都去掉,再在其中寻找S。由此证明,如果字符串S能由k个a组成的话,必定能在2S中间部分找到一个S。(这里只证明了充分性,未证明必要性)
class Solution:
def repeatedSubstringPattern(self, s):
"""
:type s: str
:rtype: bool
"""
return s in (s * 2)[1:-1] if len(s) > 1 else False
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。