以下嵌套循环的Big-O时间复杂度是多少?
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
System.out.println("i = " + i + " j = " + j);
}
}
它仍然是O(N^2)吗?
以下嵌套循环的Big-O时间复杂度是多少?
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
System.out.println("i = " + i + " j = " + j);
}
}
它仍然是O(N^2)吗?
是的,它仍然是O(n^2),它有更小的常数因子,但那并不影响O符号。
是的。回想一下大O符号的定义:根据定义,O(f(n))表示运行时间T(n) ≤ kf(n),其中k是某个常数。在这种情况下,步骤数将是(n-1)+(n-2)+...+0,这可以重排为0到n-1之和;这是
T(n)=(n-1)((n-1)+1)/2 的中文翻译为:T(n)=(n-1)×(n-1+1)/2。
重新排列一下,你就会发现T(n)总是≤1/2(n²)。由定义,因此T(n)=O(n²)。
如果忽略 System.out.println,则复杂度为N的平方。如果假设输出时间与输出的数量成线性关系(当然可能并非如此),则我猜该算法的时间复杂度为O((N^2) * log N) 。
我提出这个不是为了挑剔,而是为了指出在计算复杂性时不仅仅需要考虑显然的循环,你还需要考虑你所谓的东西的复杂性。
让我们追踪每个迭代中每个循环执行的次数。
for (int i = 0; i < N; i++) { // outer loop
for (int j = i + 1; j < N; j++) { // inner loop
System.out.println("i = " + i + " j = " + j);
}
}
在外部循环的第一次迭代中(i = 0),内部循环执行N-1
次。
在外层循环的第二次迭代(i = 1)中,内层循环执行N-2
次。
在外部循环的第三次迭代(i = 2)中,内部循环执行N - 3
次。
. . .
在外部循环的第 N - 2
次迭代中(i = N-3),内部循环执行 2
次。
在外部循环的第N-1次迭代(i = N-2)中,内部循环执行1次。
在外部循环的最后(第N个)迭代中(i = N - 1),内部循环执行0次。
因此,此代码执行的总次数是
N - 1
+ N - 2
+ N - 3
+ … + 2
+ 1
+ 0
N - 1
+ N - 2
+ N - 3
+ … + 2
+ 1
+ 0
0
+ 1
+ 2
+ … + N - 3
+ N - 2
+ N - 1
的中文翻译为:0
+ 1
+ 2
+ … + N - 3
+ N - 2
+ N - 1
。
用这个代替自然数公式中的某个部分,
(N - 1) * ((N - 1) + 1) / 2 (N - 1)*((N - 1) + 1)/ 2
(N-1)(N)/ 2
((N^2) - N) / 2
的中文翻译为:((N^2)- N)/ 2。
假设 System.out.println
的时间复杂度为常数时间 O(1)
,将 O(N^2)
翻译成中文。
Sorry, there is no context or phrase provided to translate into Chinese. Please provide the text that needs translating.
此外,请看看这些。
如果N=10,那么你的迭代次数是:10+9+8+7+6+5+4+3+2+1。(即:十次迭代加九次迭代加八次迭代...等等)。
现在,你需要在加法中找出你可以得到一个N(例如中的10)的次数:
1:(10),2:(9 + 1),3:(8 + 2),4:(7 + 3),5:(6 + 4)。这是5倍...并休息5次迭代。
现在你知道你有五十五。
10(5) + 5 translates to 10(5)+ 5 in Chinese.
关于 f(n)(或N)方面,我们可以很容易地看出这是:
f(n) = n(n/2) + n/2 = (n^2)/2 + n/2 = (n^2 + n)/2… 这正是这些嵌套循环的复杂度。
但是,考虑到大O的渐近行为,我们可以摆脱f(n)的较不重要的值,即单个n和分母。
结果:O(n^2)
是的,它将是N平方。实际步骤数将是1到N的总和,即0.5 *(N-1)^ 2(如果我没有记错的话)。大O仅考虑最高指数和没有常数,因此仍然是N的平方。
关于给定的程序:
for (int i = 0; i < n; i++)
for (int j = i; j < n; j++)
println(...);
考虑 n = 3:
i 的取值将为0、1和2。
For i = 0: println will execute 3 times
for i = 1: println will execute 2 times
for i = 2: println will execute 1 times
因此,println
函数将执行3 + 2 + 1次,即n(n + 1) / 2次。
因此O(n(n+1)/2) = O(n^2)。