增长顺序复杂的循环

时间:2015-07-13 14:49:21

标签: algorithm for-loop big-o time-complexity big-theta

对于以下代码片段,N的增长顺序是什么?

int sum = 0;
for (int i = 1; i <= N; i = i*2)
  for (int j = 1; j <= N; j = j*2)
    for (int k = 1; k <= i; k++)
        sum++;

我认为有lgN术语,但我仍然坚持评估这部分:lgN(1 + 4 + 8 + 16 + ....)。序列的最后一项是什么?我需要最后一个术语来计算总和。

2 个答案:

答案 0 :(得分:3)

你的外部循环中有一个几何级数,因此有一个封闭的形式表示你要记录日志的总和:

avcodec_open2()

准确地说,你的总和是

1 + 2 + 4 + ... + 2^N = 2^(N+1) - 1

1 + ... + 2^(floor(ld(N)) 表示基数为2的对数。

外部两个循环彼此独立,而最内层循环仅依赖于ld。最内层循环中有一个操作(增量),这意味着对最内层循环的访问次数等于求和结果。

i

这相当于 \sum_i=1..( floor(ld(N)) ) { \sum_j=1..( floor(ld(N)) ) { \sum_k=1..2^i { 1 } } } // adjust innermost summation bounds = \sum_i=1..( floor(ld(N)) ) { \sum_j=1..( floor(ld(N)) ) { -1 + \sum_k=0..2^i { 1 } } } // swap outer summations and resolve innermost summation = \sum_j=1..( floor(ld(N)) ) { \sum_i=1..( floor(ld(N)) ) { 2^i } } // resolve inner summation = \sum_j=1..( floor(ld(N)) ) { 2^(floor(ld(N)) + 1) - 2 } // resolve outer summation = ld(N) * N - 2 * floor(ld(N)) (表达式中的第二项渐渐消失为第一项)以Big-Oh表示法。

答案 1 :(得分:0)

根据我的理解,外部循环将采用log N步骤,下一个循环也将采用log N步骤,最内层循环将采用最多N步骤(尽管这是一个非常粗略的界限)。总的来说,循环的运行时复杂度最多为((log N)^2)*N,这可能会得到改善。