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