使用 big-O 来描述函数的最佳情况是否有意义?

问题描述

我有一个关于 big-O 符号的非常迂腐的问题,我想对此发表一些意见。我的一个大学科目说“如果它们的第一个元素相同,则最佳 O(1)”用于检查两个列表是否具有共同元素的问题。

我对此感到不安的是,它没有描述大输入的整个域上的函数,而是描述具有相同第一个元素的两个列表的大输入的受限域。通过只讨论函数域的子集来描述函数是否有意义?当然,当仅限于该域时,时间复杂度为 omega(1)、O(1) 和 theta(1),但这并不是描述原始函数。根据我的理解,说整个函数受 omega(1) 限制会更正确。 (和 O(m*n) 其中 m,n 是两个输入列表的大小)。

大家怎么看?

解决方法

讨论案例(正如您正确指出的那样,案例是函数域的子集)和算法运行时的界限(Omega、Oh 或 Theta)是完全正确的。它是否有用是一个更难的问题,而且是一个非常依赖情况的问题。我通常认为最好情况下的 Omega-bounds、最坏情况下的 Oh-bounds 和 Theta 边界(在所有输入的“通用”情况下,当存在这样的边界时)是最“有用的”。但是调用每个集合的第一个元素相同的输入子集,“最佳情况”,似乎是合理的用法。冒泡排序的“最佳情况”是输入的子集,它们是预先排序的数组,并且受 O(n) 的约束,优于未修改合并排序的最佳情况。

,

从根本上说,大 O 表示法是一种谈论某些数量如何缩放的方式。在 CS 中,我们经常看到它用于谈论算法运行时,但我们忘记了以下所有用例都是完全合法的:

  • 半径为 r 的圆的面积是 O(r2).
  • 半径为 r 的球体的体积是 O(r3)。
  • 掷 n 个骰子后出现 2 的预期数量为 O(n)。
  • 掷出 n 个骰子后出现的最少 2 个数为 O(1)。
  • 由 n 对平衡括号组成的字符串数量为 O(4n)。

考虑到这一点,使用大 O 符号来讨论算法在特定案例系列中的行为将如何扩展是完全合理的。例如,我们可以这样说:

  • 使用插入排序对 n 个已排序元素的序列进行排序所需的时间为 O(n)。 (还有其他未排序的序列需要更长的时间。)
  • 对具有 n 个节点的树运行广度优先搜索所需的时间为 O(n)。 (在一般图中,如果边的数量更多,这可能会更大。)
  • 按排序顺序将 n 个项目插入初始为空的二进制堆所需的时间为 On)。 (对于反向排序的元素序列,这可以是 Θ(n log n)。)

简而言之,使用渐近符号来讨论算法的受限子情况是完全可以的。更一般地说,只要您对要量化的内容准确无误,就可以使用渐近符号来描述事物的增长方式。有关这样做时是否使用 O、Θ、Ω 等的更多信息,请参阅 @Patrick87 的回答。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...