给定一个非空的字符串 s
,检查是否可以通过由它的一个子串重复多次构成。
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
s = list(s)
ss = s[1:] + s[:len(s) - 1] # 写成ss = [1:2*len(s) - 1]不对。大概就像[1,2,3] = [2]一样是不允许的。
# 第28题是给出字符串h(haystack)还有待匹配的子串n(needle)判断n是否存在于h中
# 本题 h即为字符串ss(s+s然后对新字符串掐头去尾得到),n即为字符串s
# 原因参考代码随想录视频
# 下面判断ss中是否有s
# 第一步是求s作为子串 对应的next数组
next = self.getnext(s)
# 第二步开始遍历ss 尝试在其中找到s
i = 0
j = 0
while i < len(ss):
while j > 0 and ss[i] != s[j]:
j = next[j - 1]
# 其实next的作用仅仅是 在j需要回退的时候指定j回退的位置
if ss[i] == s[j]:
i += 1
j += 1
if j == 0:
i += 1
if j == len(next):
return True
return False
# # 如果字符串是由重复的子串组成的话,可以用以下方法求出重复的基本单位。
# next = self.getnext(s)
# longest = 0
# index = 0
# for i in range(len(next)):
# if next[i] > longest:
# longest = next[i]
# index = i
# needle = ss[:len(ss) - longest] # 这样把字符串重复的基本单位就求出来了
def getnext(self, s):
next = [0] * len(s)
j = 0
for i in range(1, len(s)):
while j > 0 and s[i] != s[j]:
j = next[j - 1]
if s[i] == s[j]:
j += 1
next[i] = j
return next
之后又回看代码随想录,发现其实可以不用那么复杂在ss里找s,有更简单的方法判断:
if nxt[-1] != 0 and len(s) % (len(s) - nxt[-1]) == 0:
return True
return False