大O:这是FOR循环O(n log(n))还是O(log(n)^ 2)?

时间:2019-05-27 23:05:41

标签: performance runtime big-o

我有一个通用函数

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,不幸的是,到目前为止,由于我的老师不是很好,我不得不依靠互联网:(

2 个答案:

答案 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^k2n-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