Leetcode Merge k Sorted Lists,这一个问题主要需要考虑的问题是:如何每次以最小的代价找出最小的值。我们可以使用一个最小堆来维护,设当前非空的链的个数为noEmpty,那么,每一次找出最小值的代码为:log(noEmpty)。
最坏的情况是,所有的链表都一样长,那么有此时的时间复杂度为:total * log(n)。其中total为总的node的个数,n为需要归并的链表的数量。相关代码如下:
#include<vector>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode* result = NULL;
ListNode* result_cur = NULL;
int min = 0;
int lastIdex = lists.size();
// remove the empty list
for (int i = 0; i < lastIdex; i++) {
if (lists[i] == NULL) {
lists[i] = lists[lastIdex - 1];
lastIdex--;
i--;
}
}
buildHeap(lists, lastIdex);
while (lastIdex > 0) {
// get the first element of the head and insert
if (result != NULL) {
result_cur->next = lists[0];
result_cur = result_cur->next;
} else {
result = lists[0];
result_cur = result;
}
// remove the first
lists[0] = lists[0]->next;
if (lists[0] == NULL) {
lists[0] = lists[lastIdex - 1];
lastIdex--;
}
// heaplify the left
heaplify(lists, lastIdex, 0);
}
return result;
}
// make subtree a min heap
void heaplify(vector<ListNode*>& lists, int last, int idx) {
int left = idx * 2 + 1;
int right = idx * 2 + 2;
int max = idx;
if (left < last && lists[left]->val < lists[idx]->val) {
max = left;
}
if (right < last && lists[right]->val < lists[max]->val) {
max = right;
}
if (max != idx) {
ListNode* tmp = lists[max];
lists[max] = lists[idx];
lists[idx] = tmp;
heaplify(lists, last, max);
}
}
// building a min heap
void buildHeap(vector<ListNode*>& lists, int last) {
for (int i = last / 2 - 1; i >= 0; i--) {
heaplify(lists, last, i);
}
}
};