具有不同迭代次数的嵌套循环的大 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),还有一个很有意思的属性这些数:
其中 C
是 Euler–Mascheroni constant。因此,第一种算法的复杂度为:
关于第二个。似乎代码包含错误,或者这是一个技巧测试问题。代码解析为
for (i = 1; i < n; i++)
for(j = i; j < n; j++){
arr[j]++;
j++;
}
内循环需要
操作,因此我们可以计算出整体复杂度:
我在计算两组代码示例的 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),还有一个很有意思的属性这些数:
其中 C
是 Euler–Mascheroni constant。因此,第一种算法的复杂度为:
关于第二个。似乎代码包含错误,或者这是一个技巧测试问题。代码解析为
for (i = 1; i < n; i++)
for(j = i; j < n; j++){
arr[j]++;
j++;
}
内循环需要
操作,因此我们可以计算出整体复杂度: