繁体   English   中英

O(log n)算法用于找到具有排序i的元素与预排序列表的并集

[英]O(log n) algorithm to find the element having rank i in union of pre-sorted lists

给定两个排序列表,每个包含n个实数,是否有一个O(log n)时间算法来计算两个列表的并集中排名i的元素(其中i对应于递增顺序的索引),假设元素为这两个清单是截然不同的?

编辑:@BEN:这就是我一直在做的事情,但我仍然没有得到它。

我有一个例子;

列表A:1,3,5,7列表B:2,4,6,8

找到等级(i)= 4。

第一步:i / 2 = 2; 列表A现在包含的是A:1,3列表B现在包含的是B:2,4

         compare A[i] to B[i] i.e 

                 A[i] is less;

                 So the lists now become :

                   A: 3 
                   B: 2,4

第二步:i / 2 = 1

         List A now contains A:3
         List B now contains B:2 

         NoW I HAVE LOST THE VALUE 4 which is actually the result ...

我知道我错过了一些东西,但即使在接近一天的思考之后,我也无法想到这一点......

是:

您知道元素位于第一个列表的index [0,i]或第二个列表的[0,i]中。 从每个列表中取出元素i/2并进行比较。 继续进行二分法。

我没有包含任何代码,因为这个问题听起来很像家庭作业。

编辑:Bisection是二进制搜索背后的方法。 它的工作原理如下:

假设i = 10; (基于零的索引,我们正在寻找整体的第11个元素)。

在第一步,您知道答案是在list1(0 ... 10)或list2(0 ... 10)中。 取a = list1(5)和b = list2(5)。

如果a> b,则list1中有5个元素位于a之前,而list2中至少有6个元素位于a之前。 所以a是结果的上限。 同样,list2中有5个元素位于b之前,而list1中小于6个元素位于b之前。 所以b是结果的下限。 现在我们知道结果是在list1(0..5)或list2(5..10)中。 如果a <b,则结果在list1(5..10)或list2(0..5)中。 如果a == b我们有答案(但问题是元素是不同的,因此是!= b)。

我们只需重复此过程,在每一步将搜索空间的大小减半。 二分是指我们选择中间元素(平分线)超出我们知道的范围包括结果。

因此,这与二分搜索的唯一区别在于,在二进制搜索中,我们将比较我们正在寻找的值,但在这里我们将与另一个列表中的值进行比较。

注意:这实际上是O(log i) ,它比O(log n)更好(至少不差O(log n) 此外,对于小i(可能是i <100),实际上合并第一个i元素(线性搜索而不是二分)的操作实际上更少,因为这样更简单。 当您添加缓存行为和数据位置时,线性搜索可能会快到几千。

此外,如果i> n然后依赖于结果必须朝向任一列表的末尾的事实,则每个列表中的初始候选范围来自((in).. n)

这是你如何做到的。

让第一个列表为ListX ,第二个列表为ListY 我们需要找到ListX[x]ListY[y]的正确组合,其中x + y = i 由于x,y,i是自然数,我们可以立即将问题域约束为x*y 通过使用方程max(x) = len(ListX)max(y) = len(ListY)我们现在有一个x*y元素的子集,我们需要搜索形式[x, y]

你要做的是订购那些元素,如[i - max(y), max(y)][i - max(y) + 1, max(y) - 1] ,..., [max(x), i - max(x)] 然后,您将通过选择中间[x, y]组合来平分此列表。 由于列表是有序且不同的,因此您可以测试ListX[x] < ListY[y] 如果为真,则我们将[x, y]组合的上半部分平分[x, y]或者如果为假,则将下半部分平分。 你会保持平分,直到找到合适的组合。

我留下了很多细节,但这是它的一般要点。 确实是O(log(n))!

编辑:正如本指出这实际上是O(log(i)) 如果我们让n = len(ListX) + len(ListY)那么我们知道i <= n

合并两个列表时,您将不得不触摸两个列表中的每个元素。 如果你不触及每个元素,一些元素将被遗忘。 因此,你的理论下限是O(n)。 所以你不能这样做。

您不必排序,因为您有两个已排序的列表,并且您可以将该排序维护为合并的一部分。

编辑:哎呀,我误读了这个问题。 我认为有价值,你想找到排名,而不是相反。 如果你想找到给定值的等级,那么这是如何在O(log N)做到的:

是的,如果列表允许O(1)随机访问(即它是一个数组而不是链表),你可以在O(log N)执行此操作。

  • 在L1上进行二进制搜索
  • 二进制搜索L2
  • 对指数求和

你必须计算出数学,+ 1,-1,如果找不到元素该怎么办,但这就是想法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM