day08 466. 统计重复个数 [困难]

1.题目描述  466. 统计重复个数

由 n 个连接的字符串 s 组成字符串 S,记作 S = [s,n]。例如,["abc",3]=“abcabcabc”。

如果我们可以从 s2 中删除某些字符使其变为 s1,则称字符串 s1 可以从字符串 s2 获得。例如,根据定义,"abc" 可以从 “abdbec” 获得,但不能从 “acbbe” 获得。

现在给你两个非空字符串 s1 和 s2(每个最多 100 个字符长)和两个整数 0 ≤ n1 ≤ 106 和 1 ≤ n2 ≤ 106。现在考虑字符串 S1 和 S2,其中 S1=[s1,n1] 、S2=[s2,n2] 。

请你找出一个可以满足使[S2,M] 从 S1 获得的最大整数 M 。

示例:

输入:
s1 ="acb",n1 = 4
s2 ="ab",n2 = 2

返回:
2

 

2.思路分析

        1.按照文中数量的提示,用长字符串来做匹配是不行的,因为可能很长

        2.按照短的子串来匹配,就要考虑子串和2倍子串两种情况

        3.若N2==2*N1,那么按照一倍的倍数计算即可q=n1*N1

        4.若N2>2*N1,按照q = n1//2*N2 + n1%2*N1即可

        5.最后一步计算 M = q//n2

实际上这个思路不对,不能处理更多的情况,改为了从1开始尝试各个倍数字符串知道找到当前收益开始降低的倍数为止,但是这个思路也是不对,因为可能收益先降低后又升高到最大值,根据bad case分析,最多尝试到最小公倍数/n1倍数次,结果逻辑对了,但是超时了

 

3.debug过程

对于leetcode的困难题,印象就研究过两个,不看题解,基本上得不到ac解,还需继续努力。而且即使得到逻辑正确的解也是不断尝试摸索过程,有点费劲,后续,暂时先不考虑困难的题目了,只考虑中等题目,因为困难题目面试中说实话也很难遇到,基本上以<=中等难度为主

 

4.ac代码[运行超时](python)

class Solution(object):
    def getMaxRepetitions(self, s1, n1, s2, n2):
        """
        :type s1: str
        :type n1: int
        :type s2: str
        :type n2: int
        :rtype: int
        思路:
        1.按照文中数量的提示,用长字符串来做匹配是不行的,因为可能很长
        2.按照短的子串来匹配,就要考虑子串和2倍子串两种情况
        3.若N2==2*N1,那么按照一倍的倍数计算即可q=n1*N1
        4.若N2>2*N1,按照q = n1//2*N2 + n1%2*N1即可
        5.最后一步计算 M = q//n2
        """

        def lcm(x, y):
            #最小公倍数
            if x > y:
                greater = x
            else:
                greater = y

            while (True):
                if ((greater % x == 0) and (greater % y == 0)):
                    lcm = greater
                    break
                greater += 1
            return lcm

        def get_generate_count(s1, s2):
            # 判断s2是否可以通过s1删减某些字符得到
            i = j = 0
            s1_len = len(s1)
            s2_len = len(s2)
            count = 0
            while True:
                if i == s1_len:
                    break
                if s1[i] == s2[j]:
                    j += 1
                    if j == s2_len:
                        j = 0
                        count += 1
                i += 1
            return count

        num = get_generate_count(s1, s2)
        best_ratio = 1
        max_roi = num
        nums = [num]
        ratio = 1
        max_ratio = lcm(len(s1), len(s2))/ len(s1)
        while True:
            ratio += 1
            if ratio > n1:
                break
            tnum = get_generate_count(s1 * ratio, s2)
            nums.append(tnum)
            if tnum / ratio > max_roi:
                max_roi = tnum / ratio
                num = tnum
                best_ratio = ratio
            else:
                if ratio >= max_ratio:
                    break
        q = n1 // best_ratio * num
        if n1 % best_ratio - 1 > -1:
            q += nums[n1 % best_ratio - 1]
        return q // n2

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值