简体   繁体   English

有条件的 3 个嵌套循环的时间复杂度

[英]Time complexity of 3 nested loops with a condition

What is the time complexity (big O) of this function ?这个函数的时间复杂度(大 O)是多少? and how to calculate it ?以及如何计算?

I think it's O(N^3) but am not sure.我认为是 O(N^3) 但我不确定。 在此处输入图片说明

int DAA(int n){
    int i, j, k, x = 0;
    for(i=1; i <= n; i++){
        for(j=1; j <= i*i; j++){
            if(j % i == 0){
                for(k=1; k <= j; k++){
                    x += 10;
                }
            }
        }
    }
    return x;
}

The complexity is O(n^4)复杂度为O(n^4)

But not because you blindly drop unused iteration.但不是因为你盲目地放弃了未使用的迭代。

it's because when you consider all instruction, O(n + n^3 + n^4) = O(n^4)这是因为当你考虑所有指令时, O(n + n^3 + n^4) = O(n^4)

int DAA(int n){
   int x = 0;
   for(int i=1; i <= n; i++) // O(n)
      for(int j=1; j <= i*i; j++) // O(1+2+...n^2) = O(n^3)
         if(j % i == 0) // O(n^3) same as loop j
            for(int k=1; k <= j; k++) // O(n^4), see below
               x += 10; // O(n^4) same as loop k

   return x;
}

Complexity of conditioned inner loop条件内循环的复杂性

the loop k only execute when j%i==0 , ie {i, i*2, i*3 ... i*i}循环k仅在j%i==0时执行,即{i, i*2, i*3 ... i*i}

so for the case the inner-most loop execute, the algorithm is effectively所以对于最内层循环执行的情况,算法是有效的

int DAA(int n){
   int x = 0;
   for(int i=1; i <= n; i++) // O(n)
      for(int t=1; t <= i; t++) // O(1+2+...+n) = O(n^2)
         for(int k=1; k <= t*i; k++) // O(n^4)
               x += 10;
   return x;
}

O(n^4)


Why simply drop unused iteration not work?为什么简单地删除未使用的迭代不起作用?

let's say it's now让我们说现在

int DAA(int n){
   int x = 0;
   for(int i=1; i <= n; i++) // O(n)
      for(int j=1; j <= i*i; j++) // O(1+2+...+n^2) = O(n^3)
         if(j == i) 
            for(int k=1; k <= j; k++)
               x += 10; // oops! this only run O(n^2) time

   return x;
}
// if(j==i*log(n)) also cause loop k becomes O((n^2)log(n))
// or, well, if(false) :P

Although the innermost instruction only run O(n^2) time.虽然最里面的指令只运行O(n^2)时间。 The program actually do if(j==i) (and j++ , j<=i*i ) O(n^3) time, which make the whole algorithm O(n^3)程序实际上做了if(j==i) (and j++ , j<=i*i ) O(n^3)时间,这使得整个算法O(n^3)

Time complexity can be easier to compute if you get rid of do-nothing iterations.如果您摆脱无所作为的迭代,时间复杂度会更容易计算。 The middle loop does not do anything unless j is a multiple of i .除非ji的倍数,否则中间循环不会做任何事情。 So we could force j to be a multiple of i and eliminate the if statement, which makes the code easier to analyze.因此,我们可以强制ji的倍数并消除if语句,这使代码更易于分析。

int DAA(int n){
    int x = 0;
    for(int i=1; i <= n; i++){
        for(int m=1; m <= i; m++){  // New variable to avoid the if statement
            int j = m*i;            // The values for which the inner loop executes
            for(int k=1; k <= j; k++){
                x += 10;
            }
        }
    }
    return x;
}

The outer loop iterates n times.外循环迭代n次。 O(n) so far. O(n) 到目前为止。

The middle loop iterates 1 time, then 2 times, then... n times.中间循环迭代1次,然后2次,然后…… n次。 One might recognize this setup from the O(n 2 ) sorting algorithms.人们可能会从 O(n 2 ) 排序算法中识别出这种设置。 The loop executes n times, and the number of iterations increases to n , leading to O(n×n) complexity.循环执行n次,迭代次数增加到n ,导致 O(n×n) 复杂度。

The inner loop is executed on the order of n×n times (the complexity of the middle loop).内循环按 n×n 次的顺序执行(中间循环的复杂度)。 The number of iterations for each execution increases to n×n (the maximum value of j ).每次执行的迭代次数增加到 n×n( j的最大值)。 Similar to how the middle loop multiplied its number of executions and largest number of iterations to get its complexity, the complexity of the inner loop – hence of the code as a whole – should become O(n 4 ), but I'll leave the precise proof as an exercise.类似于中间循环如何乘以它的执行次数和最大迭代次数以获得其复杂性,内部循环的复杂性 - 因此整个代码 - 应该变成 O(n 4 ),但我将离开作为练习的精确证明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM