n或nlog(n)是否优于常数或对数时间?

时间:2014-09-17 19:55:26

标签: algorithm time-complexity

在Coursera的普林斯顿教程中,讲师解释了遇到的常见增长顺序函数。他说线性和线性运行时间是“我们努力的”,他的推理是随着输入尺寸的增加,运行时间也增加。我认为这是他犯了一个错误的地方,因为我之前听过他提到线性增长顺序对于一个有效的算法是不能令人满意的。

在他发言时,他还展示了绘制不同运行时间的图表 - 恒定和对数运行时间看起来效率更高。这是一个错误,还是这个?

8 个答案:

答案 0 :(得分:13)

在上下文中考虑O(n)和O(n log n)函数比O(1)和O(log n)函数具有更好的复杂性是错误的。在查看大O符号的典型复杂情况时:

O(1)< O(log n)< O(n)< O(n log n)<为O(n ^ 2)

请注意,这并不一定意味着它们在性能方面总是更好 - 我们可能有一个O(1)函数需要很长时间才能执行,即使它的复杂性不受元素数量的影响。这样的函数在大O表示法中看起来比在O(log n)函数中看起来更好,但在实践中实际上可能表现更差。

一般来说:复杂程度较低的函数(大O表示法)将胜过复杂程度更高的函数(大O表示法)当n足够高时

答案 1 :(得分:10)

你错过了必须做出这些陈述的更广泛的背景。不同类型的问题有不同的要求,并且通常甚至有理论上限来确定解决这些问题需要多少工作,无论手段如何。

对于排序或扫描简单集合的每个元素等操作,您可以为这些操作设置集合中元素数量的硬下限,因为输出取决于输入的每个元素。 [1]因此,O(n)或O(n * log(n))是最好的。

对于其他类型的操作,例如访问哈希表或链表的单个元素,或搜索有序集,该算法无需检查所有输入。在这些设置中,O(n)操作会非常慢。

[1]其他人会注意到,通过比较排序也有一个n * log(n)下界,来自信息论的论点。对于某些类型的输入,有基于非比较的排序算法可以胜过这个。

答案 2 :(得分:2)

一般来说,我们所追求的是我们能够做到的最好。但取决于我们正在做什么,可能是O(1),O(log log N),O(log N),O(N),O(N log N),O(N 2 ),O(N 3 ),或(或某些算法)可能是O(N!)或甚至O(2 N )。

例如,当您处理在已排序集合中进行搜索时,二进制搜索会在平凡的边界上进行,并且会给出O(log N)复杂性。如果集合中的项目分布是合理可预测的,我们通常可以做得更好 - 大约是O(log log N)。知道了,一个O(N)或O(N 2 )的算法(对于一些明显的例子)可能会非常令人失望。

另一方面,排序通常是相当高的复杂性 - "好"算法管理O(N log N),而较差的算法通常在O(N 2 )附近。因此,对于排序O(N)算法实际上是非常好的(事实上,只有相当受约束的输入类型才可能),而且我们几乎可以指望像O(log log N)这样的东西根本不是&#39可能。

更进一步,我们很乐意仅用O(N 2 )而不是通常的O(N 3 )来管理矩阵乘法。考虑到这些问题的最佳解决方案,我们只能欣喜若狂才能获得O(N 3 )中旅行商问题或子集和问题的最优,可重现的答案。通常需要O(N!)。

答案 3 :(得分:2)

具有诸如O(1)或O(Log(N))之类的次线性行为的算法是特殊的,因为它们不需要查看所有元素。在某种程度上,这是一个谬论,因为如果确实存在N个元素,则只需要读取或计算它们就可以使用O(N)。

在执行一些预处理后,通常可以使用次线性算法。考虑排序表中的二进制搜索,取O(Log(N))。如果数据最初未排序,则将首先对O(N Log(N))进行排序。如果您在同一数据集上执行许多搜索(例如K),则可以平衡排序成本。实际上,没有这种情况,搜索的成本将是O(K N),并且具有预排序O(N Log(N)+ K Log(N))。如果K>>你获胜日志(N)。

这就是说,当不允许预处理时,O(N)行为是理想的,并且O(N Log(N))也非常舒适(对于一百万个元素,Lg(N)仅为20)。你开始用O(N²)尖叫,然后更糟。

答案 4 :(得分:1)

他说这些算法是我们努力的目标,这通常是正确的。许多算法不可能比对数或线性时间更好地改进,虽然在完美世界中恒定时间会更好,但通常无法实现。

答案 5 :(得分:1)

恒定时间总是更好,因为时间(或空间)复杂性不依赖于问题大小......这不是一个很棒的功能吗? : - )

然后我们有O(N)然后是Nlog(N)

你知道吗?存在持续时间复杂性的问题!

e.g。

令A [N]为N个整数值的数组,其中N> 1。 3.查找和算法以判断前三个元素的总和是正还是负。

答案 6 :(得分:0)

我们所追求的是效率,就设计时间(或空间)复杂度而不超过其理论下限的算法而言。

例如,使用基于比较的算法,您无法在分类数组中找到比Omega(Log(N))更快的值,并且您无法比Omega(N Log(N))更快地对数组进行排序 - 在最坏的情况下。

因此,二分搜索O(Log(N))和Heapsort O(N Log(N))是有效的算法,而线性搜索O(N)和Bubblesort O(N²)则不是。

下限取决于要解决的问题,而不是算法。

答案 7 :(得分:0)

是常数时间,即O(1)优于线性时间O(n),因为前者不依赖于问题的输入大小。顺序是O(1)> O(logn)> O(n)> O(nlogn)。 我们努力的线性或线性时间因为去O(1)可能不太现实,因为在每个排序算法中我们至少需要一些比较,教授试图用他的判断树进行比较 - 比较分析,他试图对三个元素进行排序abc并证明了nlogn的下限。检查他的排序复杂度"在Mergesort演讲中。