您确实保留了日志,因为 log(n) 会随着 n 的增加而增加,并且由于它相乘而反过来会增加您的整体复杂性。
作为一般规则,您只会删除常量。例如,如果您有 O(2 * n^2),您只需说复杂度为 O(n^2),因为在功能强大两倍的机器上运行它不会影响复杂度。
同样,如果复杂度为 O(n^2 + n^2),那么您将遇到上述情况并直接说它是 O(n^2)。由于 O(log(n)) 比 O(n^2) 更优化,如果您有 O(n^2 + log(n)),您会说复杂度是 O(n^2),因为它甚至更小比 O(2 * n^2) 复杂。
O(n^2 * log(n)) 不属于上述情况,因此不应简化它。
一个正式的数学证明在这里会很好。
让我们定义以下变量和函数:
N- 算法的输入长度,
f(N) = N^2*ln(N)- 计算算法执行时间的函数。
让我们确定这个函数的增长是否以 渐近为界O(N^2)。
根据渐近符号[1]的定义,g(x)是f(x)当且仅当的渐近界: 对于 的所有足够大的值x, 的绝对值f(x)至多是 的正常数倍数g(x)。也就是说,f(x) = O(g(x))当且仅当存在一个正实数M和一个实数x0使得
|f(x)| <= M*g(x) for all x >= x0 (1)
在我们的例子中,必须存在一个正实数M和一个实数N0,使得:
|N^2*ln(N)| <= M*N^2 for all N >= N0 (2)
显然,这样M和x0不存在,因为对于任意大的 ,M有N0,使得
ln(N) > M for all N >= N0 (3)
因此,我们已经证明N^2*ln(N)不是渐近有界的O(N^2)。
参考文献:
1 : - https://en.wikipedia.org/wiki/Big_O_notation
理解大O表示法的一种简单方法是将实际步数除以具有大O的项,并验证得到常数(或小于某个常数的值).
例如,如果您的算法执行10n²⋅logn步骤:
10n²⋅logn/n²= 10 log n - >在n - >10n²时不恒定.log n不是O(n²)
10n²⋅logn/(n²⋅logn)= 10 - >常数n - >10n²⋅logn是O(n²⋅logn)
如果某个算法的复杂度=O(n^2),则可以写为O(n*n)。是O(n)吗?绝对不是。所以 O(n^2*logn) 不是 O(n^2)。您可能想知道的是 O(n^2+logn)=O(n^2)。