如何在$ C $不相交的排序数组的联合中找到$ k $ th最小的项?

时间:2015-06-27 20:56:29

标签: arrays algorithm sorting

这里有一个解释https://cstheory.stackexchange.com/questions/20944/select-in-union-of-sorted-arrays-already-known,但我发现它很不清楚。

对于如何在$ C $不相交的排序数组中找到$ k $ th最小的项目,是否有更严格概括且易于理解的算法?

1 个答案:

答案 0 :(得分:1)

基本上,在任何给定时间,我们必须同时比较所有数组中的最小项,找到最小的,然后逐步更新它。我们基本上想要一堆。

设A [i]为第i个数组,A [i] [j]是该数组的第j个元素。排序使得A [i] [0]是第i个数组中最小的。设H是最小堆,让我成为另一个长度为C的数组。

I = [0] * C
array = [(A[i][0], i) for i in range(C)]
H = heapify(array)

在堆中,元组按字典顺序排序,即按元组中的第一个元素排序。接下来,我们这样做:

for i in range(k-1):
    z = H.peek()[1] # which array smallest came from
    I[z] += 1 # update index for that array
    H.replace((A[z][I[z]], z)) # remove smallest, update

k_smallest = H.peek()[0]

它的python,除了我假装python实际上有一个很好的堆。我们的想法是维护一个大小等于数组数的堆,每个数组的当前元素最小。每次我们弹出最小的,并从该数组中获取下一个元素。这样,每个阵列总是一个代表"在堆中,我们始终确保堆顶部是我们尚未处理的所有元素中最小的。我们丢弃第一个k-1,然后查看第k个。

运行时间:堆操作将花费O(log(C)),并且你必须做k次,所以O(klog(C))。但是,您还必须最初创建堆,因此它总计为O(klog(C)+ C)。

编辑:我之前的解决方案实际上是O((k + C)log(C)),因为堆创建。我现在将堆创建更改为单个" heapify"只花费C。