📜  在 k 个已排序数组中查找第 m 个最小值

📅  最后修改于: 2021-10-28 02:11:35             🧑  作者: Mango

给定 k 个大小可能不同的排序数组,在合并数组中找到第 m 个最小值。
例子:

Input: m = 5     
      arr[][] = { {1, 3},
                  {2, 4, 6},
                  {0, 9, 10, 11}} ;
Output: 4
Explanation The merged array would
be {0 1 2 3 4 6 9 10 11}.  The 5-th 
smallest element in this merged
array is 4.

Input: m = 2
      arr[][] = { {1, 3, 20},
                  {2, 4, 6}} ;
Explanation The merged array would
be {1 2 3 4 6 20}. The 2nd smallest element would be 2. 
Output: 2

一个简单的解决方案是创建一个输出数组,然后将所有数组一一复制到其中。最后,使用排序输出数组。这种方法需要 O(N Logn N) 时间,其中 N 是所有元素的计数。
一个有效的解决方案是使用堆数据结构。基于堆的解决方案的时间复杂度为 O(m Log k)。
1. 创建一个大小为 k 的最小堆并将所有数组中的第一个元素插入堆中
2.重复以下步骤m次
…..a) 从堆中移除最小元素(最小值总是在根)并将其存储在输出数组中。
…..b) 从提取元素的数组中插入下一个元素。如果数组没有更多元素,则什么都不做。
3. 打印最后移除的项目。

CPP
// C++ program to find m-th smallest element
// in the merged arrays.
#include 
using namespace std;
 
// A pair of pairs, first element is going to
// store value, second element index of array
// and third element index in the array.
typedef pair > ppi;
 
// This function takes an array of arrays as an
// argument and all arrays are assumed to be
// sorted. It returns m-th smallest element in
// the array obtained after merging the given
// arrays.
int mThLargest(vector > arr, int m)
{
    // Create a min heap with k heap nodes. Every
    // heap node has first element of an array
    priority_queue, greater > pq;
 
    for (int i = 0; i < arr.size(); i++)
        pq.push({ arr[i][0], { i, 0 } });
 
    // Now one by one get the minimum element
    // from min heap and replace it with next
    // element of its array
    int count = 0;
    int i = 0, j = 0;
    while (count < m && pq.empty() == false) {
        ppi curr = pq.top();
        pq.pop();
 
        // i ==> Array Number
        // j ==> Index in the array number
        i = curr.second.first;
        j = curr.second.second;
 
        // The next element belongs to same array as
        // current.
        if (j + 1 < arr[i].size())
            pq.push({ arr[i][j + 1], { i, j + 1 } });
 
        count++;
    }
 
    return arr[i][j];
}
 
// Driver program to test above functions
int main()
{
    vector > arr{ { 2, 6, 12 },
                              { 1, 9 },
                              { 23, 34, 90, 2000 } };
 
    int m = 4;
    cout << mThLargest(arr, m);
 
    return 0;
}


输出:
9

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。