forked from kamyu104/LeetCode-Solutions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
merge-k-sorted-lists.cpp
133 lines (115 loc) · 3.14 KB
/
merge-k-sorted-lists.cpp
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Time: O(n * logk), n is the length of the result list.
// Space: O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
// Merge two by two solution.
class Solution {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
if (lists.empty()) {
return nullptr;
}
int left = 0, right = lists.size() - 1;
while (right > 0) {
lists[left] = mergeTwoLists(lists[left], lists[right]);
++left;
--right;
if (left >= right) {
left = 0;
}
}
return lists[0];
}
private:
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
ListNode dummy{0};
auto curr = &dummy;
while (l1 && l2) {
if (l1->val <= l2->val) {
curr->next = l1;
l1 = l1->next;
} else {
curr->next = l2;
l2 = l2->next;
}
curr = curr->next;
}
curr->next = l1 ? l1 : l2;
return dummy.next;
}
};
// Time: O(n * logk)
// Space: O(logk)
// Divide and Conquer solution.
class Solution2 {
public:
ListNode *mergeKLists(vector<ListNode *> &lists) {
return mergeKListsHelper(lists, 0, lists.size() - 1);
}
private:
ListNode *mergeKListsHelper(const vector<ListNode *> &lists, int begin, int end) {
if (begin > end) {
return nullptr;
}
if (begin == end) {
return lists[begin];
}
return mergeTwoLists(mergeKListsHelper(lists, begin, (begin + end) / 2),
mergeKListsHelper(lists, (begin + end) / 2 + 1, end));
}
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
ListNode dummy{0};
auto curr = &dummy;
while (l1 && l2) {
if (l1->val <= l2->val) {
curr->next = l1;
l1 = l1->next;
} else {
curr->next = l2;
l2 = l2->next;
}
curr = curr->next;
}
curr->next = l1 ? l1 : l2;
return dummy.next;
}
};
// Time: O(n * logk)
// Space: O(k)
// Heap solution.
class Solution3 {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode dummy(0);
auto *cur = &dummy;
struct Compare {
bool operator() (const ListNode *a, const ListNode *b) {
return a->val > b->val;
}
};
// Use min heap to keep the smallest node of each list
priority_queue<ListNode *, vector<ListNode *>, Compare> min_heap;
for (const auto& n : lists) {
if (n) {
min_heap.emplace(n);
}
}
while (!min_heap.empty()) {
// Get min of k lists.
auto *node = min_heap.top();
min_heap.pop();
cur->next = node;
cur = cur->next;
if (node->next) {
min_heap.emplace(node->next);
}
}
return dummy.next;
}
};