题目:
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Example:
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
解法一
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
auto cmp = [](ListNode*& a, ListNode*& b) {
return a->val > b->val;
};
priority_queue<ListNode*, vector<ListNode*>, decltype(cmp) > q(cmp);
for (auto node : lists) {
if (node) q.push(node);
}
ListNode *dummy = new ListNode(-1), *cur = dummy;
while (!q.empty()) {
auto t = q.top(); q.pop();
cur->next = t;
cur = cur->next;
if (cur->next) q.push(cur->next);
}
return dummy->next;
}
};
这种解法利用了最小堆这种数据结构,我们首先把k个链表的首元素都加入最小堆中,它们会自动排好序。然后我们每次取出最小的那个元素加入我们最终结果的链表中,然后把取出元素的下一个元素再加入堆中,下次仍从堆中取出最小的元素做相同的操作,以此类推,直到堆中没有元素了,此时k个链表也合并为了一个链表,返回首节点即可
解法二
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode *dummy = new ListNode(-1), *cur = dummy;
unordered_map<int, int> m;
int mx = INT_MIN, mn = INT_MAX;
for (auto node : lists) {
ListNode *t = node;
while (t) {
mx = max(mx, t->val);
mn = min(mn, t->val);
++m[t->val];
t = t->next;
}
}
for (int i = mn; i <= mx; ++i) {
if (!m.count(i)) continue;
for (int j = 0; j < m[i]; ++j) {
cur->next = new ListNode(i);
cur = cur->next;
}
}
return dummy->next;
}
};
思路是将所有的结点值出现的最大值和最小值都记录下来,然后记录每个结点值出现的次数,这样我们从最小值遍历到最大值的时候,就会按顺序经过所有的结点值,根据其出现的次数,建立相对应个数的结点。但是这种解法有个特别需要注意的地方,那就是合并后的链表结点都是重新建立的,若在某些情况下,我们不能新建结点,而只能交换或者重新链接结点的话,那么此解法就不能使用,但好在本题并没有这种限制,可以完美过OJ