具有不同迭代的嵌套循环的大O?

时间:2017-07-26 01:26:57

标签: c runtime big-o

我在解决两组代码示例的Big O运行时间时遇到了一些麻烦,其中迭代依赖于外部循环。我对Big O运行时有一个基本的了解,我可以找出更简单的代码示例的运行时间。我不太确定某些行如何影响运行时间。

我会考虑第一个O(n ^ 2)。但是,我不确定。

for(i = 1; i < n; i++){
 for(j = 1000/i; j > 0; j--){  <--Not sure if this is still O(n)
    arr[j]++; /* THIS LINE */
 }
}

我对这个失去了一点点。 O(n ^ 3)可能是O(n ^ 2)?

for(i = 0; i < n; i++){
 for(j = i; j < n; j++){
    while( j<n ){
      arr[i] += arr[j]; /* THIS LINE */
      j++;
    }
 }
}

我发现这篇文章并将其应用于第一个代码示例,但我仍然不确定第二个。 What is the Big-O of a nested loop, where number of iterations in the inner loop is determined by the current iteration of the outer loop?

2 个答案:

答案 0 :(得分:5)

关于第一个。这是 O(n^2) !!!为了简单和可读性,让我们以伪代码的形式重写它:

for i in [1, 2, ... n]:                              # outer loop
    for j in [1, 2, ... 1000/i]:                     # inner loop
        do domething with time complexity O(1).      # constant-time operation

现在,内循环中的常量操作数(取决于外循环的参数i)可表示为:

enter image description here

现在,我们可以计算整体恒定时间操作的数量:

enter image description here

在这里,N(n)是一个谐波数(见wikipedia),这些数字有一个非常有趣的属性:

enter image description here

CEuler–Mascheroni constant的位置。因此,第一种算法的复杂性是:

enter image description here

关于第二个。似乎代码包含错误,或者它是一个技巧测试问题。代码解析为

for (i = 1; i < n; i++)
    for(j = i; j < n; j++){
        arr[j]++;
        j++;
    }

内循环需要

enter image description here

操作,因此我们可以计算整体复杂性:

enter image description here

答案 1 :(得分:2)

对于第二个循环(看起来你仍然需要答案),你有一些误导性的代码,你有3个嵌套循环,所以乍一看,运行时是O是有意义的(N ^ 3)。

然而,这是不正确的。这是因为最里面的while循环修改j,这是for循环修改的相同变量。这段代码实际上等同于下面的代码:

for(i = 0; i < n; i++){
  for(j = i; j < n; j++){
    arr[i] += arr[j]; /* THIS LINE */
    j++;
  }
}

这是因为内部的while循环将运行,递增j直到j == n,然后它就会爆发。此时,内部for循环将再次递增j并将其与n进行比较,其中它将发现j> = n,并退出。您应该已熟悉此案例,并将其识别为O(n ^ 2)。

只是注意,第二位代码不安全(技术上),因为当while循环完成运行后j再增加一次时j可能会溢出。这将导致for循环永远运行。但是,这只会在n = int_max()。

时发生