重复字符串匹配

时间:2017-10-04 00:47:16

标签: python algorithm

我做了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,有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

如果x+1 < n和B是A重复n次的子字符串,并且您已将B嵌入其中,那么您可以切断A的最后一个副本而不会击中B(意味着n不是最小的)或者A中B的开头是在第一个副本结束之后,所以你可以砍掉第一个副本(并且n不是最小的。)

因此,如果它完全适合,它必须符合x+1份。仅根据长度,它不适合< x份。因此,剩下的唯一可能性是xx+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) 进行完整搜索。