【问题标题】:Unsure about the time complexity of this code [duplicate]不确定此代码的时间复杂度 [重复]
【发布时间】:2018-07-01 09:05:30
【问题描述】:

我最近解决了https://www.geeksforgeeks.org/find-given-string-can-represented-substring-iterating-substring-n-times/上提出的一个问题

问题是确定是否可以通过迭代子字符串 n 次从子字符串中表示特定字符​​串。

例如字符串"abcabcabc"可以通过迭代子字符串"abc" 3来表示。

我想出了这个 Java 解决方案

public static boolean canForm (String str) {

    if(str.isEmpty()||str.length()==1) return true;

    int end;

    if (str.length()%2==0) {
        end = str.length()/2;
    } else {
        end = (str.length()-1)/2;
    }

    for (int i=1; i<=end; i++) {
        String s = str.substring(0,i);
        String compare = "";
        while (compare.length()<str.length()) {
         compare += s;
        }
        if (compare.equals(str)) return true;
    }

    return false;
}

问题的一个条件是解决方案为 O(n)。我的结论是 O(n) 但我不确定我的解决方案是否真的是 O(n) 或者实际上是 O(n^2) 以及为什么。

【问题讨论】:

  • 如果你能解释你是如何得出它的 O(n) 的,如果有错误你最好纠正你而不是完全回答问题。
  • 对于每次迭代,字符串变量“compare”部分由大小为 str.substring(0,i) 的子字符串构成。例如,字符串“abcd”将需要 4 + 2 = 6 个步骤来构建。如果我们将字符串的大小加倍为“abcdefghi”,它将是 8 + 4 + 3 + 2 步。因此,总步数将是某个常数乘以 n 减去另一个常数,例如 c*n - k。因此时间复杂度是O(n)。我想知道这个想法是否有错误,以便可以纠正它并防止我将来犯这个错误。
  • 请注意,由于 substringO(n) 中运行,单独的 for(...) { ... str.substring(...) ... } 已经产生 O(n^2)。因此请参阅Time complexity of Java's substring()。串联compare += scompare.equals(str) 也是如此。所有这些子表达式都在O(n) 中运行,并与包装for-loop 一起产生O(n^2)
  • 不是答案,但您可以通过首先检查 i 是否是 str.length 的除数来改进它
  • 这是我的想法。我还想到了一个替代解决方案,它涉及旋转字符串并将旋转的字符串与原始字符串进行比较。如果它们相同,则该字符串可以由一个子字符串表示 n 次。我还想到了一个 Python 解决方案,它利用了可用于字符串的乘法运算符。我只是想确定我发布的用于学习目的的解决方案的时间复杂度。

标签: java string algorithm


【解决方案1】:

您的程序在 O(n^2) 中运行,其中 n 与字符串的长度成正比。您的代码有一个 while 循环,该循环在一个迭代 n 次的 for 循环中迭代 n 次。 因此程序的顺序是O(n*n)=O(n^2)。

【讨论】:

  • 您可以通过在分析中添加重要的方法调用来改进,例如substring 和串联compare += 2
  • 这就是我感到困惑的地方。我知道它会在第一次迭代中迭代 n 次,但是每次迭代的迭代次数都会减少。所以“abcdefghi”将是 n + n/2 + 3 + n/4。它不会为每次迭代迭代 n 次。它在第一次迭代中迭代 n 次,并且在以后的每次迭代中迭代 n/(某个常数)。这就是我感到困惑的原因。
  • @CoderInLearning 你应该知道 a 是常数的 O(an) 与 O(n) 相同。
  • @cdaiga 我知道大 O 的基本原理。就像 O(n^2 + n + 1) 将是 O(n^2) 或 O(48n^3 + 6n^2 + 1) 将是 O(n^3)。感谢您的帮助,因为总和中的每个项都是 O(n)。无论是 n/2 还是 n/4,每个项的计算结果为 O(n)。超过 n 次,这将评估为 O(n^2)。所以它实际上会计算为 O(n^2)。
猜你喜欢
  • 2022-01-27
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多