[英]Algorithm with O(m (log n + log m)) time complexity for finding kth smallest element in n*m matrix with each row sorted?
[英]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)
执行此操作。
你必须计算出数学,+ 1,-1,如果找不到元素该怎么办,但这就是想法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.