【每日力扣Leetcode】459-判断一个字符串是否由子字符串重复组成

力扣题库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上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值