解法1:
利用priority queue + tuple。
记得我们需要最小堆,因为sorting是从小到大排序。而priority queue缺省是用最大堆,所以需要define class cmp 和 bool operator()。
tuple<i,j,k> 记录了k=arrays[i][j]。
时间复杂度应该是 O(N log k).
N is the total number of integers.
k is the number of arrays.
代码如下:
class cmp {
public:
// to ensure a min-heap, otherwise it is max-heap by default
bool operator() (tuple<int, int, int> &a, tuple<int, int, int> &b) {
return get<2>(a) > get<2>(b);
}
};
class Solution {
public:
/**
* @param arrays: k sorted integer arrays
* @return: a sorted array
*/
vector<int> mergekSortedArrays(vector<vector<int>> &arrays) {
tuple<int, int, int> tp; //tuple<i,j,k> => k = arrays[i][j]
priority_queue<tuple<int, int, int>, vector<tuple<int, int ,int>>, cmp> pq;
vector<int> result;
int arrayLen = arrays.size();
for (int i = 0; i < arrayLen; ++i) {
if (arrays[i].size() != 0) {
pq.push(make_tuple(i, 0, arrays[i][0]));
}
}
while(!pq.empty()) {
tuple<int, int, int> elem = pq.top();
pq.pop();
result.push_back(get<2>(elem));
get<1>(elem)++;
if (get<1>(elem) < arrays[get<0>(elem)].size()) {
pq.push(make_tuple(get<0>(elem),
get<1>(elem),
arrays[get<0>(elem)][get<1>(elem)]));
}
}
return result;
}
};
解法2:就用priority_queue定义最小堆。
代码如下:
class Node {
public:
Node(int r, int c, int v) : row(r), col(c), val(v) {}
//min-heap
bool operator < (const Node & obj) const {
return val > obj.val;
}
int row, col, val;
};
class Solution {
public:
/**
* @param arrays: k sorted integer arrays
* @return: a sorted array
*/
vector<int> mergekSortedArrays(vector<vector<int>> &arrays) {
vector<int> result;
int nRow = arrays.size();
if (nRow == 0) return result;
int nCol = arrays[0].size();
priority_queue<Node> pq;
for (int i = 0; i < nRow; ++i) {
if (arrays[i].size() > 0) pq.push(Node(i, 0, arrays[i][0]));
}
while(!pq.empty()) {
Node currTop = pq.top();
pq.pop();
result.push_back(currTop.val);
if (currTop.col + 1 < arrays[currTop.row].size()) {
pq.push(Node(currTop.row, currTop.col + 1, arrays[currTop.row][currTop.col + 1]));
}
}
return result;
}
};
另外一种写法如下:
class Node {
public:
Node(int r, int c, int v) : row(r), col(c), val(v) {}
int row, col, val;
};
class cmp {
public:
bool operator() (const Node & a, const Node & b) const {
return a.val > b.val;
}
};
class Solution {
public:
/**
* @param arrays: k sorted integer arrays
* @return: a sorted array
*/
vector<int> mergekSortedArrays(vector<vector<int>> &arrays) {
vector<int> result;
int nRow = arrays.size();
if (nRow == 0) return result;
int nCol = arrays[0].size();
priority_queue<Node, vector<Node>, cmp> pq;
for (int i = 0; i < nRow; ++i) {
if (arrays[i].size() > 0) pq.push(Node(i, 0, arrays[i][0]));
}
while(!pq.empty()) {
Node currTop = pq.top();
pq.pop();
result.push_back(currTop.val);
if (currTop.col + 1 < arrays[currTop.row].size()) {
pq.push(Node(currTop.row, currTop.col + 1, arrays[currTop.row][currTop.col + 1]));
}
}
return result;
}
};
3刷:
注意:这里是每行有序,所以用最小堆。每次
注意跟行列皆有序的LintCode 1874题的区分,那题也是用最小堆,但是没次先把最小的array[0][0]push到minHeap,然后每次pop出最小值,再把最小值的右边和下面元素push到minHeap。按那题的方法,minHeap的size()应该也是O(mnlogm)?
https://blog.youkuaiyun.com/roufoo/article/details/105308293
struct Node {
int row, col, val;
Node(int r, int c, int v) : row(r), col(c), val(v) {}
bool operator < (const Node &node) const {
return val > node.val;
}
};
class Solution {
public:
/**
* @param arrays: k sorted integer arrays
* @return: a sorted array
*/
vector<int> mergekSortedArrays(vector<vector<int>> &arrays) {
vector<int> res;
int nRow = arrays.size();
priority_queue<Node> minHeap;
for (int i = 0; i < nRow; i++) {
if (arrays[i].size() > 0) minHeap.push(Node(i, 0, arrays[i][0]));
}
while (!minHeap.empty()) {
Node topNode = minHeap.top();
minHeap.pop();
res.push_back(topNode.val);
if (topNode.col + 1 < arrays[topNode.row].size()) {
minHeap.push(Node(topNode.row, topNode.col + 1, arrays[topNode.row][topNode.col + 1]));
}
}
return res;
}
};
解法3:还是minheap,但上面的时间复杂度是O(mnlogm),下面的代码的解法的时间复杂度是O(mnlog(mn)),其实是把元素按每列的第1个元素,第2个元素这样按顺序压栈,再把top找出来,效率不高。上面的方法每次就把pop最小元素,同时把最小元素同行的下一个元素push进minHeap,这样minHeap的size一直都是k。而这里的方法每次把k个元素push进minHeap,但只pop出一个最小值,所以效率低。
class Solution {
public:
/**
* @param arrays: k sorted integer arrays
* @return: a sorted array
*/
vector<int> mergekSortedArrays(vector<vector<int>> &arrays) {
vector<int> res;
int nRow = arrays.size();
vector<int> pointers(nRow, 0);
priority_queue<int, vector<int>, greater<int>> minHeap;
minHeap.push(INT_MIN);
while (!minHeap.empty()) {
for (int i = 0; i < nRow; i++) {
if (pointers[i] >= arrays[i].size()) {
continue;
};
minHeap.push(arrays[i][pointers[i]]);
pointers[i]++;
}
if (!minHeap.empty()) {
res.push_back(minHeap.top());
minHeap.pop();
}
}
res.erase(res.begin()); //remove the fake INT_MIN pushed before the while() loop
return res;
}
};