【发布时间】:2014-02-02 12:03:34
【问题描述】:
我只是有点困惑。如果算法的时间复杂度由
给出大O符号是什么?只是 还是我们保留日志?
【问题讨论】:
标签: big-o time-complexity
我只是有点困惑。如果算法的时间复杂度由
给出大O符号是什么?只是 还是我们保留日志?
【问题讨论】:
标签: big-o time-complexity
如果这是算法的时间复杂度,那么它已经是大 O 表示法,所以,是的,保留日志。渐近地,O(n^2) 和 O((n^2)*log(n)) 之间存在差异。
【讨论】:
理解大 O 符号的一种简单方法是将实际原子步数除以大 O 项,然后验证您得到一个常数(或小于某个常数的值)。
例如,如果您的算法执行 10n²⋅logn 步:
10n²⋅logn/n² = 10 log n -> 在 n 中不恒定 -> 10n²⋅log n 不是 O(n²)
10n²⋅logn/(n²⋅log n) = 10 -> n 中的常数 -> 10n²⋅log n 为 O(n²⋅logn)
【讨论】:
在这里有一个正式的数学证明会很好。
让我们定义以下变量和函数: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) 渐近界的。
【讨论】:
您确实保留了日志,因为 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)) 不属于上述情况,不宜简化。
【讨论】:
如果某个算法的复杂度=O(n^2),它可以写成O(n*n)。是 O(n) 吗?绝对不是。所以 O(n^2*logn) 不是 O(n^2)。你可能想知道的是 O(n^2+logn)=O(n^2)。
【讨论】: