#459. 重复的子字符串
题目
给定一个字符串s,求s是否可以由多个s的子串拼接组成。
s = “abab” --> True
s = “aba” --> False
解答
直观解法
取s所有的子串(一半以内的长度即可),看s是否可以由它的子串构成并且长度可以整除。
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
# if len(s) == 1:
# return True
for i in range(1,len(s)//2 + 1):
substring = s[0:i]
dividable = True
for j in range(0, len(s) - i + 1, i):
if len(s) % i != 0 or s[j : j + i] != substring:
dividable = False
break
if dividable == True:
return True
return False
KMP算法
KMP算法最适用于查看一个串是否在另一个串中出现。
在这里,首先判定该字符串的最长共同前后缀的长度k,如果k是0,那代表该字符串没有公共的前后缀,因此绝无可能是由多个周期字符串拼接而成。
当k不为0时,把每一个最小长度的周期串看成一只小鸭子,多个小鸭子排排坐,一个小鸭子的羽毛长度 = s的长度-最长前后缀长度k。如果字符串长度可以被周期长度整除,那么代表该字符串可以由多个周期组成。
- 解答构成:getNext() 函数; 判定重复函数
class Solution:
def getNext(self, s:str) -> List[int]:
nxt = []
nxt.append(0)
x = 1
now = 0
while x < len(s):
if s[now] == s[x]:
now += 1
x += 1
nxt.append(now)
elif now:
now = nxt[now - 1]
else:
nxt.append(0)
x += 1
return nxt
def repeatedSubstringPattern(self, s: str) -> bool:
if len(s) == 1:
return False
nxt = self.getNext(s)
if nxt[len(s) - 1] != 0 and len(s) % (len(s) - nxt[len(s) - 1]) == 0:
return True
else:
return False
收获
目前学习到的两个KMP算法的应用:
- 判定一个串有没有在另一个串里出现过
- 判定一个串是否可以由一个子串重复拼接构成。