【问题标题】:Finding Big-O with multiple nested loops?寻找具有多个嵌套循环的 Big-O?
【发布时间】:2010-10-20 11:56:37
【问题描述】:
int num = n/4;
for (int i = 1; i <= num; i++) {
    for (int j = 1; j <= n; j++) {
        for (int k = 1; k <= n; k++) {
            int count = 1;
        }
    }
}

根据我读过的书,这段代码应该是O((n^3)/4)。但显然不是。要找到嵌套循环的 Big-O,你应该乘以界限吗?所以这个应该是 num *n *n 或 n/4 *n *n。

【问题讨论】:

  • 智能编译器可能会将这个循环嵌套优化为 O(1),因为它实际上并没有做任何事情。
  • 除非另有说明,否则“智能”编译器将不理会它 - 它可能是嵌入式系统中的一个定时循环,用于控制通过透析机的血流速度:-)
  • 有比创建永远不会有定义执行时间的无意义循环更好的方法来实现计时(几乎用任何语言)!

标签: loops nested big-o


【解决方案1】:

O((n^3)/4) 在大 O 表示法方面毫无意义,因为它旨在将复杂性衡量为参数的比率。除以 4 没有任何效果,因为这会改变比率的值,但不会改变其性质。

所有这些都是等价的:

O(n^3)
O(n^3/4)
O(n^3*1e6)

其他术语只有在包含n 术语时才有意义,例如:

O(n^3 / log(n))
O(n^3 * 10^n)

正如 Anthony Kanago 正确指出的那样,惯例是:

  • 只保留总和增长率最高的词:O(n^2+n) = O(n^2)
  • 去掉产品的常量:O(n^2/4) = O(n^2)

顺便说一句,我并不总是在所有情况下都同意第一条规则。这是决定函数最大增长率的好规则,但对于算法比较(a) 这样您可以智能地限制输入参数的事情,O(n^4+n^3+n^2+n) 这样的事情明显更糟不仅仅是O(n^4)

在这种情况下,应该包含依赖于输入参数的任何项。事实上,即使是常数项在那里也可能有用。例如,比较 O(n+1e100)O(n^2) - 后者将在相当长一段时间内优于前者,直到 n 变得足够大以对常数项产生影响。


(a) 当然,有些人会说不应该以这种方式使用它,但实用主义往往会在现实世界中克服教条主义 :-)

【讨论】:

  • 此外,n^3 + n 包括 + n 作为可以删除的低阶项。
  • 谢谢,@Anthony,我只是在整理一些样本,我应该在发布之前更仔细地阅读它们。
  • 仅当您的姓氏不是“Knuth”时才适用
  • 这并没有什么意义,只是没有遵循简化的约定。
【解决方案2】:

http://en.wikipedia.org/wiki/Big_O_notation 中,您可以看到像 1/4 这样的常量在确定 Big-O 表示法时不起作用。唯一有趣的事实是它是 n^3,因此是 O(N^3)。

【讨论】:

    【解决方案3】:

    一个小技术。大 O 表示法旨在根据输入的“大小”而不是数值来描述复杂性。如果您的输入是一个数字,那么输入的大小就是您的数字的位数。唉,您的算法是 O(2^N^3),其中 N 是位数。

    More on this topic

    【讨论】:

    • 你把我弄丢了,@token。这个循环中的“大小”显然是数值,而不是位数(这需要在某处的 n 上使用 log-base-10)。
    【解决方案4】:

    形式上,时间复杂度可以如下推导:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2015-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      相关资源
      最近更新 更多