为什么执行 N/2 步的代码被认为是 O(N)?
Why codes that does N/2 steps are considered O(N)?
考虑一个嵌套循环。外循环从 i=0
开始迭代 N
次,内循环从 j=i+1
开始迭代 j=N
次。所以内循环将大致执行n/2步。然而,最后,运行时被认为是 O(N2) 为什么内部循环被认为是 O(N)
而不是 O(N/2)
,因为我们还有其他具有 O(log n) 运行时间的代码?
Big-O notation 表示执行一段代码所花费的时间 复杂度 ,与某些指标成比例。通常,大括号中使用的符号表示输入大小、容器大小等数量
直觉上,O(N)
是指一个码运行的次数与大括号内包含的符号的比例,如反对 确切 次它 运行s。它在现实中可能 运行 K = N/2
次,但点 Big-O 符号试图强调的事实是,K
的值是由 [=13= 的大小来估计的]是,并且与K
.
成正比
为了进一步澄清,请注意对于足够大的 N,除以 2 并不重要,因为它只是一个常数因子。 对于足够大的 N,常量可以忽略不计 的概念对于理解和掌握各种复杂性符号(包括 Big-O.
至关重要)
您似乎混合两种不同的情况(最终公式-N**2/C
中的除法-其中C
可以 ignored: O(N**2/C) == O(N**2)
; 和 loop 中的除法: for (int j = N; j >= 1; j /= C)
where C
导致 对数 ):
for (int i = 1; i <= N; ++i)
for (int j = i + 1; j <= N; ++j)
SomeOperation(i, j);
我们数一数要执行的SomeOperation(i, j)
个数:
i j
-------------------
1 N - 1
2 N - 2
3 N - 3
..
N 0
所以我们有
(N - 1) + (N - 2) + ... + 2 + 1 + 0 ==
N * (N - 1) / 2 ==
N**2 / 2 - N / 2 ==
O(N**2 / 2 - N / 2) == O(N**2 / 2) == O(N**2)
相反(请注意 j /= 2
而不是 ++j
),这意味着 少得多 内循环
for (int i = 1; i <= N; ++i)
for (int j = N; j >= 1; j /= 2)
SomeOperation(i, j);
i j
-------------------
1 log(N)
2 log(N)
3 log(N)
..
N log(N)
我们这里有
log(N) + log(N) + ... + log(N) ==
N * log(N) ==
O(N * log(N))
考虑一个嵌套循环。外循环从 i=0
开始迭代 N
次,内循环从 j=i+1
开始迭代 j=N
次。所以内循环将大致执行n/2步。然而,最后,运行时被认为是 O(N2) 为什么内部循环被认为是 O(N)
而不是 O(N/2)
,因为我们还有其他具有 O(log n) 运行时间的代码?
Big-O notation 表示执行一段代码所花费的时间 复杂度 ,与某些指标成比例。通常,大括号中使用的符号表示输入大小、容器大小等数量
直觉上,O(N)
是指一个码运行的次数与大括号内包含的符号的比例,如反对 确切 次它 运行s。它在现实中可能 运行 K = N/2
次,但点 Big-O 符号试图强调的事实是,K
的值是由 [=13= 的大小来估计的]是,并且与K
.
为了进一步澄清,请注意对于足够大的 N,除以 2 并不重要,因为它只是一个常数因子。 对于足够大的 N,常量可以忽略不计 的概念对于理解和掌握各种复杂性符号(包括 Big-O.
至关重要)您似乎混合两种不同的情况(最终公式-N**2/C
中的除法-其中C
可以 ignored: O(N**2/C) == O(N**2)
; 和 loop 中的除法: for (int j = N; j >= 1; j /= C)
where C
导致 对数 ):
for (int i = 1; i <= N; ++i)
for (int j = i + 1; j <= N; ++j)
SomeOperation(i, j);
我们数一数要执行的SomeOperation(i, j)
个数:
i j
-------------------
1 N - 1
2 N - 2
3 N - 3
..
N 0
所以我们有
(N - 1) + (N - 2) + ... + 2 + 1 + 0 ==
N * (N - 1) / 2 ==
N**2 / 2 - N / 2 ==
O(N**2 / 2 - N / 2) == O(N**2 / 2) == O(N**2)
相反(请注意 j /= 2
而不是 ++j
),这意味着 少得多 内循环
for (int i = 1; i <= N; ++i)
for (int j = N; j >= 1; j /= 2)
SomeOperation(i, j);
i j
-------------------
1 log(N)
2 log(N)
3 log(N)
..
N log(N)
我们这里有
log(N) + log(N) + ... + log(N) ==
N * log(N) ==
O(N * log(N))