关于性能:具有最坏情况时间复杂度O(n)的算法总是比具有最坏情况时间复杂度O(n ^ 2)的算法快吗?

Is an algorithm with a worst-case time complexity of O(n) always faster than an algorithm with a worst-case time complexity of O(n^2)?

这个问题出现在我的算法课上。我的想法是:

我认为答案是否定的,最坏情况下时间复杂度为o(n)的算法并不总是比最坏情况下时间复杂度为o(n^2)的算法快。

例如,假设我们有总时间函数s(n)=999999999 n和t(n)=n^2。那么很明显,s(n)=o(n)和t(n)=o(n^2),但t(n)比s(n)快,所有n<9999999。

这种推理有效吗?我有点怀疑,虽然这是一个反例,但它可能是错误想法的反例。

非常感谢!


big-o表示法对任何给定输入的算法速度都没有说明;它描述了时间如何随着元素数量的增加而增加。如果您的算法在固定时间内执行,但该时间是1000亿年,那么对于大范围的输入,它肯定比许多线性、二次甚至指数算法慢。

但这可能不是真正的问题所在。问题是,具有最坏情况复杂度o(n)的算法a1是否总是比具有最坏情况复杂度o(n^2)的算法a2更快,并且通过更快,它可能指的是复杂度本身。在这种情况下,您只需要一个反例,例如:

  • A1有正常的复杂度O(log n),但最坏的复杂度O(n^2)。
  • A2具有正态复杂度O(n)和最坏情况复杂度O(n)。

在本例中,A1通常比A2更快(即缩放更好),尽管它具有更大的最坏情况复杂性。


在任何意义上,您都是正确的,您为语句提供了一个反例。如果是考试,那么句号,应该给你满分。

然而,为了更好地理解大O符号和复杂性,我将在下面分享我自己的推理。我还建议您在困惑时始终考虑以下图表,尤其是O(n)和O(n^2)行:

enter image description here

大O记号

当我第一次学习计算复杂性时,我自己的推理是,

Big-O notation is saying for sufficient large size input,"sufficient" depends on the exact formula (Using the graph, n = 20 when compared O(n) & O(n^2) line), a higher order one will always be slower than lower order one

这意味着,对于较小的输入,无法保证高阶复杂度算法的运行速度会低于低阶复杂度算法。

但是big-o表示法告诉你一个信息:当输入大小不断增加时,保持增加……直到"足够"的大小,在这之后,一个更高阶的复杂度算法将总是较慢的。这样一个"足够"的大小是保证存在的*。

最坏时间复杂性

Big-O表示法提供了算法运行时间的上界,取决于输入的结构和算法的实现,它通常具有最好的复杂度、平均复杂度和最坏的复杂度。

著名的例子是排序算法:QuaskOrths.

快速排序,最坏情况为O(n^2)

合并排序,最坏情况为O(n lg n)

但是,快速排序基本上总是比合并排序快!

因此,如果您的问题是关于最坏情况的复杂性,那么快速排序和合并排序可能是我能想到的最好的反例(因为这两种方法都是常见的和著名的)

因此,结合两个部分,无论从输入大小、输入结构、算法实现的角度来看,您的问题的答案都是否定的。


既然问题是说Always,这就意味着只要找到一个反例就足以证明答案是否定的。

例如O(n^2)和O(n logn),但O(n^2)和O(n)也是如此

一个简单的例子是冒泡排序,在排序数组之前,您可以一直比较对。气泡排序是O(n^2)。如果对已排序的数组使用冒泡排序,它将比使用其他时间复杂度o(nlogn)算法更快。


这里讨论的是最坏情况下的复杂性,对于某些算法来说,最坏情况在实际应用程序中永远不会发生。

如果说一个算法比另一个算法运行得更快,则意味着对于所有大小的输入数据,它都运行得更快。因此,对您的问题的答案显然是否定的,因为最坏情况下的时间复杂性不是运行时间的精确度量,而是最坏情况下操作数量增长的顺序。

在实践中,运行时间取决于实现,而不仅仅是关于这一数量的操作。例如,人们必须关心内存分配、缓存效率、空间/时间局部性。显然,最重要的是输入数据。

如果您希望一个算法比另一个算法运行得更快,同时具有更高的最坏情况复杂度的示例,请查看所有排序算法及其运行时间(取决于输入)。