两个数组中的第k个最小数字,一个排序,另一个未排序

时间:2018-12-05 18:29:34

标签: arrays algorithm min

两个排序数组已经有一个answer。但是,在我的问题中,其中一个数组未排序。

假设X[1..n]Y[1..m]其中n < m。 X已排序,Y未排序。找到X U Y的第k个最小数的有效算法是什么。

MinHeap可用于查找未排序数组中的第k个最小数字。但是,这里对这些数组之一进行了排序。我可以想到:

 1. Building a `MinHeap` for `Y`
 2. i = 1, j = 1
 3. x1 = extract Min from Y
 4. x2 = X[i]; 
 5. if j == k: return min(x1, x2)
 5. if x1 < x2: j++; goto 3
 6. else: j++; i++; goto 4 

效率高且正确吗?

2 个答案:

答案 0 :(得分:1)

没有帮助,但是您必须扫描Y。这需要O(m),因此您做得比O(m)还要好。

但是quickselect的平均表现为O(m)。基本上,该算法只是进行快速排序,只是您忽略了所有没有最终答案的分区。

鉴于n < m,我们可以简单地将一个数组连接到另一个数组并进行快速选择。

请注意,平均性能不错,但最差的情况是二次性能。要解决此问题,如果进度不够快,则可以切换到中位数算法的中位数,该算法可以保证快速排序的性能(尽管常量错误)。如果您不熟悉它,那就是将数组分为5组的方法,找到每个组的中位数,然后重复直到您减少到1个元素为止。然后将该元素用作整个数组的枢轴。

答案 1 :(得分:1)

从已排序的数组(X)中最小提取k个项目的最大堆。这需要O(k)时间。

对于未排序数组(Y)中的每个项目,如果它小于堆中最大的项目(根),则从堆中删除根并添加新项。最糟糕的情况是O(m log k)。

完成后,第k个最小的数字将在堆的顶部。

尽管第二部分的最坏情况是O(m log k),但平均情况要好得多,因为通常只有一小部分项目必须插入堆中。