每天一道leetcode 统计重复个数(循环节)

Posted rower

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每天一道leetcode 统计重复个数(循环节)相关的知识,希望对你有一定的参考价值。

统计重复个数(循环节)

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

答:

class Solution:
    def getMaxRepetitions(self, s1: str, n1: int, s2: str, n2: int) :
        diction=dict()
        s1cnt,s2cnt,n=0,0,0
        while True: #寻找循环节node
            s1cnt += 1
            for i in s1:
                if i==s2[n]:
                    n+=1
                    if n==len(s2):
                        n,s2cnt=0,s2cnt+1
            if n in diction:
                s1_first,s2_first=diction[n]
                s1_node,s2_node=s1cnt,s2cnt
                break
            else:
                diction[n]=(s1cnt,s2cnt)
        #每几个s1包含几个s2
        each=(s1cnt-s1_first,s2cnt-s2_first)
        #S1中s2的数目
        cnt=s2_first+(n1-s1_first)//each[0]*each[1]
        #S1中剩余的匹配
        re=(n1-s1_first)%each[0]#求出剩下的s1的个数,再去暴力匹配s2
        for i in range(re):
            for i in s1:
                if i == s2[n]:
                    n += 1
                    if n == len(s2):
                        n, cnt = 0, cnt + 1
        return cnt//n2

解析做法:

emm,这题有点难搞,刚开始是直接暴力,直接超时,思考后选择匹配出S2的s1个数,但没有用循环节,这种复杂因素很多并且我没有处理好。

后来无奈看了解析,知道了使用循环节(类似小数点无先循环,不算刚开头无序部分)

技术图片

由循环计算得到没几个s1就可以得到一个s2,利用n1计算结果,还没结束哦,S1剩下的s1虽然不能构造一个循环节但是仍然有机会匹配出s2(s2绝大多数不等于循环节),所以利用剩下的s1个数暴力匹配s2

注意:

  • 最终结果要除于n2
  • j计算循环节个数和剩余s1过程中要处理好开头不是循环节的“无序”部分,就是这部分

技术图片

以上是关于每天一道leetcode 统计重复个数(循环节)的主要内容,如果未能解决你的问题,请参考以下文章

每天一道Rust-LeetCode(2019-06-07)

每天一道Rust-LeetCode(2019-06-11)

每天一道leetCode

每天一道LeetCode--172. Factorial Trailing Zeroes

POJ2409 Let it Bead

Leetcode 466.统计重复个数