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