Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 在n个元素的数组中使用二进制搜索查找k个不同的键_Arrays_Algorithm_Search_Time Complexity - Fatal编程技术网

Arrays 在n个元素的数组中使用二进制搜索查找k个不同的键

Arrays 在n个元素的数组中使用二进制搜索查找k个不同的键,arrays,algorithm,search,time-complexity,Arrays,Algorithm,Search,Time Complexity,比如说,我有一个n个元素的排序数组。我想使用二进制搜索在这个数组中找到两个不同的键k1和k2 一个基本的解决方案是分别对它们应用二进制搜索,比如两次调用两个键,这将使时间复杂度保持在2(logn) 我们是否可以针对不同的k键使用任何其他方法来解决此问题,kk1,可以将第二次搜索限制为i1..n,否则将其限制为0..i1 最好的情况是对搜索键进行排序,这样每次新的搜索都可以从最后一次搜索的位置开始。你可以找到计算一般情况下不同方案复杂性的学术文章,即使用最小比较次数合并两个可能非常不同长度的排序序

比如说,我有一个n个元素的排序数组。我想使用二进制搜索在这个数组中找到两个不同的键k1和k2

一个基本的解决方案是分别对它们应用二进制搜索,比如两次调用两个键,这将使时间复杂度保持在2(logn)


我们是否可以针对不同的k键使用任何其他方法来解决此问题,k您可以通过遍历一次共享搜索路径来降低真正的复杂性(尽管它仍然是相同的大O)。也就是说,开始二进制搜索,直到所处的元素位于要查找的两个项目之间。此时,生成一个线程以继续二进制搜索范围内超过当前透视元素的一个元素,并生成一个线程以继续二进制搜索范围内位于当前透视元素之前的另一个元素。返回两个结果。:-)

编辑:

正如奥利·查尔斯沃思(Oli Charlesworth)在评论中提到的那样,您确实要求任意数量的元素。但是,同样的逻辑可以扩展到任意数量的搜索键。以下是一个例子:

您有一组搜索键,如下所示:

searchKeys = ['findme1', 'findme2', ...]
您具有将搜索键映射到找到的值的键值数据结构:

keyToValue = {'findme1': 'foundme1', 'findme2': 'foundme2', 'findme3': 'NOT_FOUND_VALUE'}
现在,按照与此编辑之前相同的逻辑,您可以在关键点发散的每个线程上传递一个“pruned”
searchKeys
数组。每次找到给定键的值时,都会更新
keyToValue
映射。当
searchKeys
数组中没有更多要搜索的范围,但仍然有值时,您可以假设找不到这些键,并且可以更新映射以某种方式表示该值(一些
null
-可能类似值?)。当所有线程都已联接(或通过使用计数器)时,返回映射。这里最大的好处是,您不必重复任何两个键可能共享的初始搜索逻辑

第二次编辑:


正如Mark在回答中所说,对搜索键进行排序只需查看键范围中的第一项即可。

您完成的每个搜索都可以用于细分输入,以提高效率。例如,假设与k1对应的元素位于索引i1。如果k2>k1,可以将第二次搜索限制为i1..n,否则将其限制为0..i1


最好的情况是对搜索键进行排序,这样每次新的搜索都可以从最后一次搜索的位置开始。

你可以找到计算一般情况下不同方案复杂性的学术文章,即使用最小比较次数合并两个可能非常不同长度的排序序列。本文分析了最著名的方案之一,黄和林的方案,并参考了其他方案和黄和林的原始论文


它看起来很像一个合并,它逐步遍历较小列表中的每个项目,在较大列表中跳过,步长是两个列表大小的比率。如果它发现它在大列表中走得太远,它可以使用二进制搜索在它所走的值之间找到匹配项。如果它走得不够远,它会再走一步。

^你是对的。不过,您可以轻松地将此概念应用于
k
项。我会更新我的答案。是的,这是一个好主意!但是,between元素可以是正确的键之一,因为二进制搜索无法告诉您between元素我不知道你说的是什么意思。你指的是你所处的轴心元素吗?在你移动到一个高或低的范围之前,你应该检查一下。您声明数组已排序。通过二进制搜索,您将访问所有相关条目。你不应该错过任何东西。@Vinay:是的,我是在说枢轴元素。但我明白了。谢谢+我还提供了1个用于对搜索键进行排序的文件。在我的回答中遗漏了这个细节。:-)哦对对!钥匙必须按顺序排列,以获得最佳情况。谢谢