当前位置: 首页 > 知识库问答 >
问题:

为什么在排序数组中查找指定值的速度不可能快于O(log n)?

朱令
2023-03-14

对cs来说很新鲜...在一次演讲的结尾,我的AP计算机科学老师提到在排序数组中找到指定值的比较模型是“大欧米茄(log n)”,我的理解是,这意味着完成这个任务的速度不可能比O(log n)快?你能帮我弄明白为什么吗?谢谢你!

共有1个答案

陈欣荣
2023-03-14

让我们假设您有一个由n个项组成的数组。如果在这个数组中执行查找,那么该查找可以返回n+1个值中的一个:对于n个索引中的任何一个,“the item is not presented”或者“the item is presented at index i”。

现在,假设允许您的算法使用数组的唯一方法是通过询问以下形式的问题:“项是否大于或等于索引i中的项?”对于i的一些选择,让我们想象一下,你问一个形式为k总时间的问题。然后,有2k种可能的方式可以使比较恢复。要了解原因,有两个选项来说明第一个比较的方式(“是”或“否”)。第二次比较有两个选项(“是”或“否”),第三次比较有两个选项。所有这些2相乘得到2k

我们现在有两个制约因素:

  1. 任何正确的算法都必须能够返回n+1个不同选项中的一个。
  2. 对于k个比较,这些比较有2k种可能的方法。

这意味着我们必须有n+1≤2k,因为否则搜索算法没有足够的可能结果来覆盖所有n+1个可能结果。取两边的对数基数为2给出lg(n+1)≤k,因此进行比较的次数必须为?(log n)。

换种说法--如果您的算法进行的查询太少,那么就没有足够的方法进行比较,以确保产生每个可能的选项。

需要注意的是,有一些算法,在某些假设的前提下,可以比这更好。例如,插值搜索可以在预期时间O(log log n)内找到排序数组中的项,前提是数据看起来像线性函数。然而,最坏情况的运行时仍然是?(log n),因为这是一个基于比较的算法。更好的性能来自对数据分布的附加假设。

融合树可以在时间O(log n/log w)内执行搜索,其中w是机器字大小,前提是值是适合于单个机器字的整数。这可以改进到O(sqrt(log n/log log n))的惊人运行时。众所周知,如果n个值都适合于一个机器字,那么前面的下界说您不能比(非常不寻常的运行时)O(min{log w/log log w,sqrt(log n/log log n)})做得更好,其中w是机器字大小。这些算法通过在单个机器词上使用创造性操作并行地进行多次比较,从而超过?(log n)下限。

 类似资料:
  • 我发现了这个流行的9岁左右的问题,并决定重新检查它的结果。 所以,我有AMD Ryzen 9 595 0x、Clang++10和Linux,我从问题中复制粘贴了代码,下面是我得到的: 分类-0.549702秒: 未排序-0.546554s: 我很确定的事实是,未经排序的版本被证明是快了3ms,只是噪音,但它似乎不再慢了。 那么,CPU的架构发生了什么变化(以至于不再慢一个数量级)? 以下是多次运行

  • 问题内容: 我接受了采访,并且有以下问题: 在不到O(n)的时间内从排序数组中查找唯一数字。 我给出了解决方案,但这是O(n)的。 编辑: 排序后的数组大小约为200亿,唯一数约为1000。 问题答案: 分而治之 : 查看排序序列的第一个和最后一个元素(初始序列为)。 如果两者相等,则序列中的唯一元素是第一个(无论序列有多长)。 如果不同,则划分序列并为每个子序列重复。 一般情况下解决 O(log

  • 在这篇文章中,为什么处理排序数组比处理随机数组更快,它说分支预测是排序数组性能提升的原因。 但是我刚刚使用Python尝试了这个例子;我认为排序数组和随机数组没有区别(我尝试了字节数组和数组;并使用line_profile来分析计算)。 我遗漏了什么吗? 这是我的代码:

  • 本文向大家介绍php在数组中查找指定值的方法,包括了php在数组中查找指定值的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php在数组中查找指定值的方法。分享给大家供大家参考。具体如下: php中有两个函数可以判断数组中是否包含指定的值,分别是:array_search($value, $array)和in_array($value, $array),array_search可以找

  • 问题内容: 这是一段C ++代码,显示了一些非常特殊的行为。由于某些奇怪的原因,奇迹般地对数据进行排序使代码快了将近六倍: 不使用std::sort(data, data + arraySize);,代码将在11.54秒内运行。 使用排序的数据,代码将在1.93秒内运行。 最初,我认为这可能只是语言或编译器异常,所以我尝试了Java: 具有类似但不太极端的结果。 我首先想到的是排序将数据带入缓存,

  • 我不明白堆排序的空间复杂度是怎样的O(1)?虽然快速排序不使用任何额外的数组(即就地),但在最坏情况下其空间复杂度为O(n),在最佳情况下为O(lg n),因为在递归调用的后端使用堆栈。我说得对吗? 堆排序也是如此。虽然,它是就地的,但是由于Build-Heap函数调用Max-Heapify函数,所以它的空间复杂度应该等于Max-Heapify,即O(lg n)。不是吗?此外,稍后在根节点调用Ma