看过一些网上的方法,大都是照搬过来的,本人的思路和网上的一致---使用最小堆,但没有封装的Class,简单易懂
(priority_queue可看另一篇https://blog.csdn.net/znzxc/article/details/86592356)
分为4部分:最小堆节点的定义、建立堆、向下调整、k路合并
需要堆排序基础。
总体思路如下:先建立堆,进行堆排序,获取首元素添加进output,改变首元素,向下调整一次,再获取首元素,,,,如此往复,直到output的大小等于所有数组的元素和
// 定义最小堆节点
struct MinHeapNode
{
MinHeapNode(int a, int b, int c)
:val(a),i(b),j(c){}
int val; // 带排序元素
int i; // 数组索引,element是从哪个数组取得
int j; // 元素索引,下一个element的索引
};
void make_MinHeap(vector<MinHeapNode> & harr)
{
int i = harr.size()/2 - 1;
while (i >= 0)
{
fixdown(harr,i);
i--;
}
}
void fixdown(vector<MinHeapNode> & harr,int i)
{
MinHeapNode key = harr[i];
int j = 2 * i + 1;
while (j < harr.size())
{
if (j + 1 < harr.size() && harr[j].val > harr[j + 1].val)
j++;
if (key.val <= harr[j].val)
break;
harr[i] = harr[j];
i = j;
j = 2 * i + 1;
}
harr[i] = key;
}
vector<int> mergeKArrays(vector<vector<int>> &arr)
{
vector<int> output;
vector<MinHeapNode> harr;// 创建一个大小为k的最小堆,堆中元素为k个数组中的每个数组的第一个元素
int numcounts = 0;//总元素数目
for (int i = 0; i < arr.size(); i++)
{
harr.push_back(MinHeapNode(arr[i][0],i,1));
numcounts += arr[i].size();
}
make_MinHeap(harr); // 对上述大小为k的数组建堆
while(output.size() < numcounts)
{
// 取堆顶,存结果
MinHeapNode &root = harr[0];
output.push_back(root.val);
// 替换堆顶
if (root.j < arr[root.i].size())
{
root.val = arr[root.i][root.j];
root.j++;
}
// 当前数组元素用完了,设堆顶为无穷大
else
root.val = INT_MAX; //INT_MAX is for infinite
fixdown(harr,0);
}
return output;
}