LeetCode 466 - Count The Repetitions - Hard ( Python)

Define S = [s,n] as the string S which consists of n connected strings s. For example, ["abc", 3] ="abcabcabc".

On the other hand, we define that string s1 can be obtained from string s2 if we can remove some characters from s2 such that it becomes s1. For example, “abc” can be obtained from “abdbec” based on our definition, but it can not be obtained from “acbbe”.

You are given two non-empty strings s1 and s2 (each at most 100 characters long) and two integers 0 ≤ n1 ≤ 106 and 1 ≤ n2 ≤ 106. Now consider the strings S1 and S2, where S1=[s1,n1] and S2=[s2,n2]. Find the maximum integer M such that [S2,M] can be obtained from S1.

Example:

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

Return:
2

思路1:Brute force. 我们在s1中找出全部的单个s2,(遍历s1)然后把这个数量除以n2就可以。但是这样做的话,可能n1很大,会造成超时。因为此时的时间复杂度是O(n1*s1)

思路2:A better brute force. 我们不需要全部遍历完s1, 我们只需要在s1中找到s2出现的规律就可以。比如说s1 = ‘abcabcabc‘,s2= ‘a‘。我们会发现每一个s1的block(‘abc‘)a都是出现1次。那么总共会有n1*1次出现s2, n1*1/n2就是最大程度s2会出现的个数了。所以下一步我们需要寻找的是s2在s1中出现的规律。我们用一个pos数组来记录每一个s1 block在开头的位置会遇到的s2的index。如果我们发现在某一个block中,s1开头的遇到的index等于此时指针遍历到s2的index,那么意味着repetition已经出现过了,我们要找的pattern已经找到了。计算出pre_count, pattern_count以及remaining count,得到的结果除以n2就是我们的最终答案。步骤:1 构造counter 和pos两个数组。分别用来记录s1中每一个block开头遇到的s2的count数量以及相当于的在s2中的index位置。数组的大小为len(s2)+1.      2 两个指针一个i先遍历从0到n1-1,另一边j遍历从0到len(s1)-1.如果s1[j] == s2[index]. increment index. 如果index等于len(s2)。那么意味我们已经完全找到了s2.此时count+=1,index重新归零。当j遍历完一遍的时候,也就是我们遍历完一个s1的时候,更新此时的counter[i] pos[i]( counter[i] = count, pos[i] = index).      3 用另一个指针k从0到i遍历,如果我们发现了重复,也就是之前有一个pos[k]等于现在的index. 那么我们计算三个部分,pre_count, pattern_count,remaining_count. pre_count等于counter[k],pattern_count = (counter[i]-counter[k]) *(n1 - k - 1) // (i-k). remain_count = counter[k+(n1-1-k) % (i-k)] - counter[k]. 所以我们得到pre_count, pattern_count, remaing count 之后,三者相加除以n2,得到的就是值。     4 如果没有出现repetition pattern,也就是循环没有进入到上面第3步的时候,我们得到的counter的最终值,counter[n1-1], 除以n2得到的就是答案。

时间复杂度 O(len(s1)*len(s2)) 空间复杂度 O(len(s2))用来储存s2的大小。
class Solution:
    def getMaxRepetitions(self, s1: str, n1: int, s2: str, n2: int) -> int:
        if n1 == 0: return 0 

        pos = [0] * (len(s2) + 1)
        counter = [0] * (len(s2) + 1)

        index = 0
        count = 0 

        for i in range(n1):
            for j in range(len(s1)):
                if s1[j] == s2[index]:
                    index += 1
                if index == len(s2):
                    index = 0
                    count += 1
            counter[i] = count
            pos[i] = index 

            for k in range(i):
                if pos[k] == index: # means the same k and the same index meet each other again. Because index = pos[i].
                    pre_count = counter[k]
                    patten_count = (counter[i] - counter[k]) * ((n1-1-k) //(i-k))
                    remain_count = counter[k+(n1-1-k) % (i-k)] - counter[k]

                    return int((pre_count + patten_count + remain_count) / n2)
        return int(counter[n1-1] / n2 ) 


原文地址:https://www.cnblogs.com/sky37/p/12242014.html

时间: 2024-10-10 04:25:05

LeetCode 466 - Count The Repetitions - Hard ( Python)的相关文章

第七周 Leetcode 466. Count The Repetitions 倍增DP (HARD)

Leetcode 466 直接给出DP方程 dp[i][k]=dp[i][k-1]+dp[(i+dp[i][k-1])%len1][k-1]; dp[i][k]表示从字符串s1的第k位开始匹配2^k个s2串需要的长度 最后通过一个循环 累积最多可以匹配多少个s2串 除以n2下取整就是答案 用倍增加速后 总的复杂度nlogn 而本题的n非常小 轻松AC 体会到倍增的魅力了吧. const int maxn=100+1,INF=1e+9; long long int dp[maxn][30]; cl

【leetcode 字符串】466. Count The Repetitions

https://leetcode.com/problems/count-the-repetitions/description/ 找循环节 https://www.cnblogs.com/grandyang/p/6149294.html 原文地址:https://www.cnblogs.com/itcsl/p/9061427.html

466. Count The Repetitions

Define S = [s,n] as the string S which consists of n connected strings s. For example, ["abc", 3] ="abcabcabc". On the other hand, we define that string s1 can be obtained from string s2 if we can remove some characters from s2 such th

[LeetCode] 038. Count and Say (Easy) (C++/Python)

索引:[LeetCode] Leetcode 题解索引 (C++/Java/Python/Sql) Github: https://github.com/illuz/leetcode 038. Count and Say (Easy) 链接: 题目:https://leetcode.com/problems/Count-and-Say/ 代码(github):https://github.com/illuz/leetcode 题意: 数数,第一个是 1,第二个是数前一个数:1 个 1,就是 11

leetcode 【 Pascal's Triangle 】python 实现

题目: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,Return [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ] 代码:oj测试通过 Runtime: 46 ms 1 class Solution: 2 # @return a list of lists of integers 3 def generat

LeetCode:Count and Say

1.题目名称 Count and Say(按照数字重复出现计数并生成字符串) 2.题目地址 https://leetcode.com/problems/count-and-say/ 3.题目内容 英文:The count-and-say sequence is the sequence of integers beginning as follows 中文:给出正整数n,返回"count-and-say"序列的第n项 说明: count-and-say序列形如:1, 11, 21, 1

[leetcode]Binary Tree Level Order Traversal @ Python

原题地址:http://oj.leetcode.com/problems/binary-tree-level-order-traversal/ 题意:二叉树的层序遍历的实现. 解题思路:二叉树的层序遍历可以用bfs或者dfs来实现.这里使用的dfs实现,代码比较简洁.实际上,二叉树的先序遍历就是dfs实现.   比如一棵树如下: 1 /  \ 2       3 /    \    /   \ 4     5  6    7    二叉树的先序遍历为{1,2,4,5,3,6,7},可以看到这个遍

LeetCode:Count Primes - 统计质数数量

1.题目名称 Count Primes(统计质数数量) 2.题目地址 https://leetcode.com/problems/count-primes/ 3.题目内容 英文:Count the number of prime numbers less than a non-negative number, n. 中文:统计正整数n以内(不含n本身)质数的数量 4.一个TLE的方法 从1到n,考察每个数字是否为质数.这个方法由于花费时间较长,不能满足题目中对时间的要求. 一段实现此方法的Jav

[leetcode]Search in Rotated Sorted Array @ Python

原题地址:https://oj.leetcode.com/problems/search-in-rotated-sorted-array/ 题意: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in