棘手的Big-O复杂性

时间:2010-06-06 12:54:01

标签: big-o asymptotic-complexity

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 值,它可能产生影响,或者算术运算,无关紧要,算作基本操作并且可以省略?

3 个答案:

答案 0 :(得分:11)

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

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

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

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

  

或算术运算,在什么尺度上无关紧要,算作基本运算并可以省略?

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:2)

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指的是log to base 2