leetcode刷题日记- 重复叠加字符串匹配

  • 题目描述:
  • 给定两个字符串 a 和 b,寻找重复叠加字符串 a 的最小次数,使得字符串 b 成为叠加后的字符串 a 的子串,如果不存在则返回 -1。
    注意:字符串 “abc” 重复叠加 0 次是 “”,重复叠加 1 次是 “abc”,重复叠加 2 次是 “abcabc”。

  • 示例:
    -输入:a = “abcd”, b = “cdabcdab”
    输出:3
    解释:a 重复叠加三遍后为 “abcdabcdabcd”, 此时 b 是其子串。
    输入:a = “abcd”, b = “cdabcdab”
    输出:3
    解释:a 重复叠加三遍后为 “abcdabcdabcd”, 此时 b 是其子串。
    输入:a = “abc”, b = “wxyz”
    输出:-1

  • 提示
    1 <= a.length <= 104
    1 <= b.length <= 104
    a 和 b 由小写英文字母组成

  • 解析:这个问题可以拆解为两个部分来看,首先我们考虑最简单的情况,给定一个字符串a,b,判断b是不是a的子串,这个就很简单了,我们用一个很简单的滑动窗口就可以解决了。接下来我们在考虑a是一个可以变动的字符串,每次变动只能重复叠加其自身,这里有两种情况,如果b有a没有的字母,那么无论叠加多少次都会失败,第二种情况是b的字母a全有,但是b的字母顺序,a无论叠加多少次都不能匹配成果,比如a=“abcd”,b=“dca”,这种情况无论a叠加到多少次都是枉然,那么我们怎么判断这种情况从而让其终止叠加,返回匹配失败的结果呢?假设a的字符串长度是la,b的长度的lb,那么如果lb如果能在la的有限次重复中匹配成功,那么当其最小重复次数k,假设有已经有la*k(记为a1)>lb,那么lb一定能在a1*2中匹配成功,我们可以用反证法来证明,假设,b不能在a1*2匹配成功,在a1*3中匹配成功,那么其需要跨越三个a1,这显然不合理的,因为这违背了la*k>lb
    在这里插入图片描述
  • 所以那么lb一定能在a1*2中匹配成功
    在这里插入图片描述
  • 所以我们的终止条件就出来了k>2 and len(a*k)//2 > len(b),这里输入k>2是避免,a字符串一开始的长度就超过的b长度的两倍的情况。到这里题目答案就呼之欲出了,代码如下。
class Solution:
    def repeatedStringMatch(self, a: str, b: str) -> int:
        """
        给定两个字符串 a 和 b,寻找重复叠加字符串 a 的最小次数,使得字符串 b 成
        为叠加后的字符串 a 的子串,如果不存在则返回 -1
        >>>self.repeatedStringMatch( "abcd", "cdabcdab")
        >>>3
        """
        if len(set(a)) < len(set(b)):
            return -1
        def helpFuc(a, b):
           """
           判断b是否是a的子串
           >>>helpFuc("aab", "aa")
           >>>True
           >>>helpFuc("abc", "bd")
           >>>False
           """ 
            if len(a) < len(b):
                return False
            for i in range(len(a)-len(b)+1):
                if a[i:i+len(b)] == b:
                    return True
            return False
        ans = 1
        while True:
            if helpFuc(a*ans, b):
                return ans
            else:
                ans += 1
            if ans > 2 and len(a*ans)//2 > len(b):
                return -1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lemon_tttea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值