在之前的面试中有遇到这个问题,当时答得不是很满意,所以,下来之后把这个题完整的写了一下。
问题:有K个长度为N的有序数组,将着这些个数组合并为一个有序的数组。
将原问题解决后,我又将原问题修改了一下:
有K个长度不定的有序数组,将这些数组合并为一个有序数组;
三种解法:
- 申请一个数组,将所有的元素添加到该数组中,使用sort()函数,直接进行排序;
- 归并排序;两两归并,使用merge()函数;
- 构造小根堆;
第一种解法的时间复杂度为:O(nlog2n)
第二种解法的时间复杂度为:O(knlogn)
第三种解法的时间复杂度为:O(mnlogn)(m为元素总个数)
第一二种解法,比较简单,这里不再赘述。下面只分析第三种解法;
解法三解题思路:
- 首先遍历所有的数组,确定最终所有元素的个数(count);
- 创建一个大小为count的数组用来保存最终结果,再创建一个大小为K的小根堆;(小根堆保存的元素类型,是结构体)
- 先将每个数组的第一个元素插入到小根堆中,进行一次堆排序;
- 重复下面的操作,直至元素全部插入结果集中:
a. 取出堆顶元素(堆中最小元素),保存到结果中;
b. 将堆顶元素所在数组的下一个元素替换到堆顶,如果堆顶元素是其所在数组的最后 一个,将堆顶元素替换成INT_MAX;
c. 进行一次堆排序;
下面是该题的详细解法:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Node
{
int val;
int col;
int row;
Node(int _val, int _row, int _col)
:val(_val)
,row(_row)
,col(_col)
{
}
};
//向下调整
void Adjust(vector<Node*>& heap, int parent)
{
size_t child = parent * 2