【问题标题】:Leetcode 686 Repeated String Match Having Trouble Understanding the ExplanationLeetcode 686 重复字符串匹配无法理解解释
【发布时间】:2019-11-11 03:22:22
【问题描述】:

我很难理解为什么 Leetcode 的重复字符串匹配的解决方案只能达到 q + 1 次 A 重复(如果 A.length()

我阅读了其他 StackOverflow 解决方案以及 Leetcode 讨论页面,但我仍然无法完全理解该解决方案。

算法解释为:

Imagine we wrote S = A+A+A+.... If B is to be a substring of S, we 
only need to check whether some S[0:], S[1:], ..., S[len(A) - 1:] 
starts with B, as S is long enough to contain B, and S has period 
at most len(A).

Now, suppose q is the least number for which len(B) <= len(A * q). 
We only need to check whether B is a substring of A * q or A * 
(q+1). If we try k < q, then B has larger length than A * q and 
therefore can't be a substring. When k = q+1, A * k is already big 
enough to try all positions for B; namely, A[i:i+len(B)] == B for i 
= 0, 1, ..., len(A) - 1.

实现如下:

class Solution {
  public int repeatedStringMatch(String A, String B) {
      int q = 1;
      StringBuilder S = new StringBuilder(A);
      for (; S.length() < B.length(); q++) S.append(A);
      if (S.indexOf(B) >= 0) return q;
      if (S.append(A).indexOf(B) >= 0) return q+1;
      return -1;
  }
}

我知道当 A.length()

我的直觉是,在 A 重复若干次之后,就会建立一个模式,如果 B 不属于该模式/字符序列,那么无论你重复 A 多少次,B 都不会是重复 A 的子串。

但是,我只是不知道为什么它必须是与 B 的长度相匹配的副本数,或者在 A.length() = B.length() 之后添加的另外 1 个副本。

如果有人能为我解决这个困惑,将不胜感激。谢谢。

【问题讨论】:

    标签: java string stringbuilder mod


    【解决方案1】:

    我想你已经明白了大部分, 所以让你看另一个基本的例子。

    ampleex
    itsalreadyhereexample
    exam
    

    假设 B 是 example 而 A 是上述之一。


    对于第一种情况 A.length() == B.length()
    我们检查它是否是一个子字符串并得到 no 作为答案。
    所以我们再次添加它并得到'ampleexampleex'
    现在我们得到 A 包含 B 的结果。


    对于第二种情况 A.length() > B.length()
    我们检查它是否是一个子字符串并得到A包含B的结果。

    (如果它不在这里,我们仍然需要检查它是否在重复中,
    相当于第一种情况)


    对于第三种情况 A.length() 所以我们重复它直到我们覆盖B的长度
    并获取examexam

    我们看到它不在其中,所以我们再次添加它,
    但它仍然不存在 (examexamexam)。


    我们需要这样做的原因是因为它可能是一个更特殊的情况。
    B 可以类似于xamexame - 基本上是重复 As 变体之一。

    (在这种情况下,可能的变化是重复xameamexmexa。)

    在这种情况下,它必须是比B更长的重复形式, 这就是 q+1 的来源。

    让我们更详细地看一下重复:
    B的长度最多为(A.length()*q)+x,其中x为[0, A.length]。

    A = exam
    B = xame[xame]
    

    B 仍然是 A 的重复,但最后一个重复中的每个字符都是可选的。

    examexam
     xame
     xamex
     xamexa
     xamexam
    
    examexamexam
     xamexame
    

    向 S 添加另一个 exam,不会改变任何事情,因为我们已经涵盖了所有可能性(从现在开始不会出现新模式)。

    如果它不在那里,它就不能是一个复制品。其他场景 - 在哪里 它可能是一个子字符串 - 已被第一种和第二种情况所涵盖。


    我希望通过这个示例可以帮助您消除困惑。 如果不只是问你不明白的地方。

    【讨论】:

    • 感谢您的澄清。我得到了一种特殊情况,即 A 的开头可以附加到 A 的末尾并生成 B;但是,我的主要困惑是为什么我们允许在 q+1 处停止?超过 q+1 是什么原因导致冗余?我将如何凭直觉知道这一点?
    • 我假设您对案例 1 和 2 没有问题,所以我只为第 3 个案例添加了更多详细信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    • 2020-12-15
    • 2012-11-30
    • 1970-01-01
    • 2012-02-20
    • 1970-01-01
    • 2021-06-23
    相关资源
    最近更新 更多