23. 合并K个升序链表

困难 · 分治 · 堆

题目

23. 合并K个升序链表
官方题解

普通的归并写法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* addToTail(ListNode* tail, ListNode* addNode) {
        addNode->next = nullptr;
        tail->next = addNode;
        return tail->next;
    }

    ListNode* mergeKLists(vector<ListNode*>& lists) {
        ListNode* dummyHead = new ListNode(-1);
        ListNode* tail = dummyHead;
        lists.erase(remove(lists.begin(), lists.end(), nullptr), lists.end());
        while (lists.size()) {
            if (lists.empty()) break;
            ListNode* minNode = lists[0];
            int minList = 0;
            for (int i = 0; i < lists.size(); i ++) {
                if (lists[i]->val < minNode->val) {
                    minNode = lists[i];
                    minList = i;
                }
            }
            lists[minList] = lists[minList]->next;
            if (lists[minList] == nullptr) lists.erase(lists.begin() + minList);
            tail = addToTail(tail, minNode);
        }
        return dummyHead->next;
    }
};

堆优化

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
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)> pq(cmp);
        for (ListNode* list : lists) {
            if (list) {
                pq.push(list);
            }
        }
        ListNode* dummyHead = new ListNode(-1);
        ListNode* tail = dummyHead;
        while (!pq.empty()) {
            ListNode* node = pq.top();
            pq.pop();
            tail->next = node;
            tail = node;
            if (node->next) {
                pq.push(node->next);
            }
        }
        return dummyHead->next;
    }
};