我做了leetcode.com的竞赛52,但我无法理解解决方案。问题陈述是:
给定两个字符串A和B,找到A必须重复的最小次数,使得B是它的子字符串。如果没有这样的解决方案,则返回-1。
例如,A =“abcd”,B =“cdabcdab。
返回3,因为重复A三次(“abcdabcdabcd”),B是>子串;和B不是A重复两次的子串 ( “abcdabcd”)。
解决方案是:
def repeatedStringMatch(self, A, B):
"""
:type A: str
:type B: str
:rtype: int
"""
times = int(math.ceil(float(len(B)) / len(A)))
for i in range(2):
if B in (A * (times + i)):
return times + i
return -1
其中一位合作者的解释是:
A必须重复足够的次数,使得它至少与> B(或更多)一样长,因此我们可以得出结论,答案的理论下界>是B的长度/长度甲设x为理论下界,即ceil(len(B)/ len(A))。
答案n只能是x或x + 1
我不明白为什么n只能是x或x + 1,有人可以帮忙吗?
答案 0 :(得分:0)
如果x+1 < n
和B是A重复n
次的子字符串,并且您已将B嵌入其中,那么您可以切断A的最后一个副本而不会击中B(意味着n
不是最小的)或者A中B的开头是在第一个副本结束之后,所以你可以砍掉第一个副本(并且n
不是最小的。)
因此,如果它完全适合,它必须符合x+1
份。仅根据长度,它不适合< x
份。因此,剩下的唯一可能性是x
和x+1
份。 (并且可以找到每个都是答案的例子。)
答案 1 :(得分:0)
假设我们有两个字符串 m = "abcde"
和任意 11 个字符的字符串 "e_abcde_abcde"
, n
需要搜索。由于要匹配 11 位数字,因此所需的最小字符数为 11,由于整数舍入,这需要 ((n/m)+1)=3
最小集进行搜索。现在结束位置取决于开始位置,并且每组 length(m)
元素中最多有 m
个唯一的起点。所以我们可以从每个位置开始,直到第一组用完。最后一次尝试可能会转到 m_last = 4
,因此匹配字符串的最后一个元素将转到 (n/m+2)
集。第一套用完后,上面的模式用完,没有新的搜索。因此,我们需要 (n/m + 2) * length (m)
进行完整搜索。