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

Big O of nested loop that with varying iterations?

我在计算两组代码示例的 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++;
    }
 }
}

我找到了这个 post 并将其应用于第一个代码示例,但我仍然不确定第二个。 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?

对于第二个循环(看起来您仍然需要答案),您有一些误导性的代码,其中有 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 循环完成 运行ning 后,如果您再递增它一次,j 可能会溢出。这将导致 for 循环永远 运行 。但是,这只会在 n = int_max().

时发生

关于第一个。是不是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)可以表示为:

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

这里,N(n)是调和数(见wikipedia),还有一个很有意思的属性这些数:

其中 CEuler–Mascheroni constant。因此,第一种算法的复杂度为:


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

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

内循环需要

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