为什么此代码段为O(n)?

时间:2019-02-24 22:39:30

标签: big-o

假定此代码段的复杂度为O(n)。但是,我不明白为什么。

sum = 0;
for (k = 1; k <= n; k *= 2)  // For some arbitrary n
  for (j = 1; j <= k; j++)
    sum++;

现在,我了解到外循环本身就是O(log n),所以为什么加上内循环才能使这个O(n)

2 个答案:

答案 0 :(得分:5)

让我们暂时假设 n 是2的幂。

内部循环的最终迭代将运行 n 次。之前的迭代将运行 n / 2次,倒数第二次迭代 n / 4次,依此类推,直到第一次迭代将运行一次。这形成了一个序列,总和为2 n -1次迭代。这是O( n )。

(例如,如果 n = 16,则内部循环总共运行1 + 2 + 2 + 4 + 8 + 16 + = 31。)

答案 1 :(得分:1)

m = floor(lg(n))。然后将2^m = C*n1 <= C < 2一起使用。内循环中的步骤数k类似于:

1, 2, 4, 8, ..., 2^m = 2^0, 2^1, ..., 2^m

因此,操作总数为

2^0 + 2^1 + ... + 2^m = 2^{m+1} - 1      ; think binary
                      = 2*2^m - 1
                      = 2*C*n - 1        ; replace
                      = O(n)