力扣题库459,判断一个字符串是否由子字符串重复组成。
题目链接点这里。
题目描述
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例 1:
输入: “abab”
输出: True
解释: 可由子字符串 “ab” 重复两次构成。
示例 2:
输入: “aba”
输出: False
示例 3:
输入: “abcabcabcabc”
输出: True
解释: 可由子字符串 “abc” 重复四次构成。 (或者子字符串 “abcabc” 重复两次构成。)
解题思路
一看到题目首先想到是利用正则表达式,但是引入了新的模块似乎不太合理。
之后利用枚举法应该是个很容易想到的思路,从头开始截取子字符串,然后判断能不能通过重复组成完整原始字符串。最长只需要截取到原始字符串的一半即可,更长的子字符串无论如何不会符合条件的。
于是将两种解法都提交了,做为原始答案。
初始答案
正则表达式
import re
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
return re.match(r'^([a-z]+)\1{1,}$',s)
解释一下这里的正则表达式。[a-z]+
表示至少1个任意小写字母组成的字符串,([a-z]+)\1
中\1
代表分组的编号,也就是小括号内的内容,这里表示将小括号的内容马上重复了一遍。([a-z]+)\1{1,}
中的{1,}
表示将前面的\1
的内容至少重复一遍,换句话说也就是将小括号内的内容至少重复两遍。最后加上了^
和$
表示开头和结尾表示对整个字符串进行匹配(这里的^
其实可以省略)。
提交以后执行用时252ms,击败了10.54%的提交。这里因为使用了第三方模块,没法做一个时间复杂度的计算。
枚举法
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
def isSubString(str1,str2):
times = len(str2)//len(str1)
if not times==int(len(str2)/len(str1)):
return False
else:
if str2==str1*times:
return True
else:
return False
for i in range(1,len(s)//2+1):
subStr = s[0:i]
if isSubString(subStr,s):
return True
else:
continue
return False
这里定义了一个临时函数isSubstring()
专门用来判断一个字符串能不能通过重复组成另一个字符串。
首先如果长度不能整除肯定就不行,python3中的/
符号即使是两个整数整除也返回浮点数,而//
如果是两个整型相除则一定会向下取整返回整型结果。之后如果能够整除,就直接判断能否通过重复多遍变为另一个字符串。这里直接用*
符号对字符串进行重复,比较常见于print('-'*10)
这种格式化输出的场景。
利用一个循环,截取不同长度的内容做为子字符串,注意这里range()
要从1开始取值,不然的话会取到长度为0的子字符串,会报错。
因为要遍历半个字符串,所以时间复杂度为O(N),提交以后执行耗时220马上,击败了14.69%的提交,比前面的正则表达式还是进步了一点点。
改进答案
很惊讶大家的提交执行的都这么快,结果发现答案根本看不太懂。官方解法中用了4种方式来解答此题,除了刚才的枚举法,还用了双倍字符串法,KMP算法和优化后的KMP算法。因为不是很理解这里就先不展示了,留作以后进一步学习了再回来填坑。
注意事项
针对正则表达式,虽说时间效率不高,至少学习到了小括号去完整重复匹配的规则,千万注意不能直接在小括号后面使用{}
,+
等等重复规则,因为小括号内也不是固定内容,所以并不能达到完整重复匹配的目的。
In [46]: if re.match(r'(abc){2,}','abcabc'): print('yes')
yes
In [47]: if re.match(r'(abc){2,}','abcabcd'): print('yes')
yes
In [51]: if re.match(r'([a-z]{3}){2,}','abdcab'): print('yes')
yes
同时也要注意python中除法的两种运算符号,/
和//
,如果是俩整型数相除,第一个一定返回浮点型,第二个一定返回整型。如果是两个浮点数相除,一定都返回浮点数。
我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。