【问题标题】:Order Of Growth complicated for loops增长顺序复杂的 for 循环
【发布时间】:2015-07-13 14:49:21
【问题描述】:

对于下面的代码片段,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 + ....)。序列的最后一项是什么?我需要最后一项来计算总和。

【问题讨论】:

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


    【解决方案1】:

    你的外部循环有一个几何级数,所以你想要取对数的总和有一个封闭的形式:

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

    准确地说,你的总和是

    1 + ... + 2^(floor(ld(N))
    

    ld 表示以 2 为底的对数。

    外面的两个循环是相互独立的,而最里面的循环只依赖于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 表示法中,这等于 O(N log N)(表达式中的第二项相对于第一项渐近消失)。

    【讨论】:

    • 我对未定义O(.)-O(.) 的答案有疑问。它是什么?一组减法? (显然不是......)请解决这个问题,我很乐意投票。
    • @amit。你完全正确。象征意义是为了表达一个时间复杂度支配另一个时间复杂度,但实际上它滥用了符号。更正答案。
    【解决方案2】:

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

    【讨论】:

    • 它也是O(n!),但信息量不是很大...正如您所说,界限并不紧密,请参阅@collapsar 答案以了解应该如何计算它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多