【问题标题】:Tricky Big-O complexity棘手的 Big-O 复杂性
【发布时间】:2011-02-28 09:06:16
【问题描述】:
public void foo(int n, int m) {
    int i = m;

    while (i > 100) {
        i = i / 3;
    }
    for (int k = i ; k >= 0; k--) {
        for (int j = 1; j < n; j *= 2) {
            System.out.print(k + "\t" + j);
        }
        System.out.println();
    }
}

我认为复杂度是 O(logn)。
也就是作为内循环的产物,外循环——执行次数永远不会超过100次,所以可以省略。

我不确定的是 while 子句,是否应该将其合并到 Big-O 复杂性中?对于非常大的 i 值,它可能会产生影响,或者算术运算,无论规模多大,都算作基本运算并且可以省略?

【问题讨论】:

  • +1 标记它的作业和诚实!
  • while 计数 - 它是 O(log m)

标签: big-o asymptotic-complexity


【解决方案1】:

while 循环是O(log m),因为您不断将m 除以3,直到它低于或等于100

因为 100 在你的情况下是一个常数,所以可以忽略,是的。

正如你所说,内循环是O(log n),因为你将j乘以2直到它超过n

因此总复杂度为O(log n + log m)

还是算术运算,不管是什么规模,都算基本运算,可以省略吗?

算术运算通常可以省略,是的。但是,这也取决于语言。这看起来像 Java,看起来您正在使用原始类型。在这种情况下,可以考虑算术运算O(1),是的。但是,如果你使用大整数,那就不行了,因为加法和乘法不再是O(1)

【讨论】:

  • @Sekhat:同意,我也给了他+1 :)
【解决方案2】:

复杂度为 O(log m + log n)。

while 循环执行 log3(m) 次 - 一个常量 (log3(100))。外层 for 循环执行固定次数(大约 100 次),内层循环执行 log2(n) 次。

【讨论】:

    【解决方案3】:

    while 循环将 m 的值除以 3,因此此类操作的数量将为 log(base 3) m

    对于 for 循环,您可以将操作数视为 2 个求和 -

    求和 (k = 0 到 i) [求和 (j = 0 到 lg n) (1)] 求和 (k = 0 到 i) [lg n + 1] (lg n + 1) ( i + 1) 将是操作的总数,其中对数项占主导地位。

    这就是复杂度为 O(log (base3) m + lg n) 的原因 这里的 lg 是指以 2 为底的日志

    【讨论】:

    • 您能解释一下为什么要加 O(log (base3) m + lg n) 为什么不相乘?
    • 在我看来应该是 log (base3) m + (log (base3) m *lg n)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多