【问题标题】:Best time complexity of a single loop?单循环的最佳时间复杂度?
【发布时间】:2021-09-16 09:42:01
【问题描述】:

我有一个非常简单的问题,我有这个循环:

for (int i=0; i<n; i++) {
    "some O(n) stuff here)"
}

这个算法的最佳时间复杂度是多少? O(n)? (for 循环 O(1) * O(n) 东西) 或者 O(n^2)? (for 循环 O(n) * O(n) 循环内的东西)时间> for 循环本身是否会像往常一样被视为 O(n),还是会被视为 O(1) 因为它只会在最好的情况下进行 1 次循环?

【问题讨论】:

  • " 对于最好的情况,它只会产生 1 个循环?"假设 n = 5,那么只有 1 次迭代怎么会有“最佳情况”?
  • @jarod42 所以 O(n^2) 是三者中最好、平均和最坏情况的时间复杂度?
  • @ViliusBaranauskas 就大 O 而言,是的,即使您可以在循环内执行 O(k) 工作,它仍然是 O(n*k),或更一般的 O(n^2) , 总是。唯一重要的是功能增长,这就是我们在这里分析的内容。我们对实际值不感兴趣,例如 n = 5, k = 9。这样的性能影响可以忽略不计,也不重要,编译器可能只是展开它并给我们留下一个,从技术上讲,O(1),我不确定这是否正确,因为这不是大 O 的意思。

标签: time-complexity computer-science


【解决方案1】:

你是对的,如果“stuff”的最佳运行时间是恒定的(甚至为零),那么最好的时间复杂度是 O(N)(甚至是 Θ(N))。

无论如何,如果已知“stuff”是最好的情况 Ω(f(N)),那么最好的总时间是 Ω(N f(N))。

【讨论】:

    【解决方案2】:

    如果您的循环正在执行O(n) 的工作n 次,那么时间复杂度将为O(n^2)。你可以称之为最坏的情况。最佳情况和平均情况将基于您的some O(n) stuff,该some O(n) stuff 在您的循环的每次迭代中执行。

    让我们举一个冒泡排序算法的简单例子:

        for (int i = 0; i < n - 1; ++i) {
            for (int j = 0; j < n - i - 1; ++j) {
                if (a[j] > a[j + 1]) {
                    swap(&a[j], &a[j + 1]);
                }
            }
        }
    

    时间复杂度将始终为O(n^2),无论数组是否排序(不考虑顺序 - 升序或降序)。

    但这可以通过观察nth 传递找到nth 最大元素并将其放入最终位置来优化。因此,内部循环可以避免在运行 nth 时间时查看最后的 n − 1 项:

        for (int i = 0; i < n - 1; ++i) {
            swapped = false;
            for (int j = 0; j < n - i - 1; ++j) {
                if (a[j] > a[j + 1]) {
                    swap(&a[j], &a[j + 1]);
                    swapped = true;
                }
            }
            if (swapped == false) {
                break;
            }
        }
    

    现在最好的情况时间复杂度是O(n),即当数组按升序排序时(在上述实现的上下文中)。平均和最坏情况仍然是O(n^2)

    因此,要确定算法的最佳情况时间复杂度,您必须向我们展示some O(n) stuff 的实现,如果没有实现,那么至少展示您尝试实现的算法。

    【讨论】:

      【解决方案3】:

      正如你所说,它是 O(n^2)。 因为你做了 n 次 O(n) 操作。

      【讨论】:

      • 这是错误的,因为 O(N) 只是一个上限,而 最佳 的情况可能是 O(1)。
      • @YvesDaoust 我认为这种说法是错误的,因为这不是我们看待“最佳情况”的方式,否则每个算法的最佳情况都是 O(1),因为首先不使用它是最好的case 场景,这是一个恒定时间的操作,即使这意味着没有时间用于它。
      • @Kaihaku:不,“不使用它”是不允许的。简单的语句for (i= 0; i &lt; N; i++) {} 是 O(N) 但绝不是 O(1)。现实世界的 O(N) 算法具有 O(1) 的最佳情况并不罕见。 (例如插入数组。)
      • @YvesDaoust 这就是我的观点。否则,您可以为for(i = 0; i &lt; 5; i++) {} 提出相同的论点,您可以争辩说它的O(1)。最好的情况可能是“O(1)”,不管这意味着什么,但 for 循环的最佳复杂度总是O(N),因为它不是N = 5,或者N = 42NN,总是,函数,这就是为什么提问者的例子的最佳复杂性总是O(N^2),不多也不少。
      • @Kaihaku:还是错了。您的第一个循环无疑是 O(1),因为它不依赖于 N。在条件 i
      猜你喜欢
      • 2013-12-08
      • 2019-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-08
      • 2017-04-11
      • 2016-12-17
      相关资源
      最近更新 更多