两个排序数组已经有一个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
效率高且正确吗?
答案 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),但平均情况要好得多,因为通常只有一小部分项目必须插入堆中。