我有一个通用函数
for i from 1 to n; i = 2i; {
for j from 1 to i; {
(constant time stuff)
}
}
对于此功能,我知道的第一行for i from 1 to n; i = 2i;
是O(log(n))。 (constant time stuff)
行无关紧要,因为它是O(1),所以谁在乎呢?
但是中线for j from 1 to i;
是我遇到麻烦的地方。
我假设此行的Big O与第一行相同,因为它遵循与第一行相同的模式,其中i在每次迭代后都会加倍,这将使其变为O(log(n)) ,但也可能是O(n)吗?
此外,如果实际上是O(log(n))* O(log(n)),那是O(log(n)^ 2)正确吗?
对不起,我刚开始学习Big O,不幸的是,到目前为止,由于我的老师不是很好,我不得不依靠互联网:(
答案 0 :(得分:1)
这个FOR循环是O(n log(n))还是O(log(n)^ 2)?
都不是。
外部循环迭代log n
次。如果内部循环每次具有相同的迭代次数,则可以将外部循环的迭代次数乘以内部循环的操作次数。但这不是,所以我们不能。
实际上,我们实际上需要总结内部循环的迭代次数:第一次,迭代一次。第二次,两次。然后是四个,然后是八个,依此类推,直到最终到达n
。因此,我们有总和1 + 2 + 4 + ... + n
,在此我们知道该总和具有log n
的总和,换句话说,就是k=0
的{{1}}到n
的总和。该总和恰好等于2^k
。 2n-1
显然位于2n-1
中,所以这就是您的答案。
答案 1 :(得分:0)
您有点滥用符号
sum_{i=1..log n} ( sum_{j=1..2^i} O(1) )
= sum_{i=1..log n} (2^i * O(1))
= O(2^(log n + 1))
= O(n)
可以通过简单的归纳证明第二个但也是最后一个等价物:
2^(n+1)
= 2 * 2^n
= 2 * (sum_{i=0..n-1} (2^i) + 1)
= sum_{i=1..n} (2^i) + 2
= sum_{i=0..n} (2^i) + 1
具有基本情况n=1: 2^1 = 1+1 = 2^0+1
。