-
Notifications
You must be signed in to change notification settings - Fork 257
/
merge-k-sorted-lists.cpp
151 lines (134 loc) · 3.54 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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Time: O(n * logk)
// Space: O(1)
/**
* Definition of ListNode
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
// Merge two by two solution.
class Solution {
public:
/**
* @param lists: a list of ListNode
* @return: The head of one sorted list.
*/
ListNode *mergeKLists(vector<ListNode *> &lists) {
if (lists.empty()) {
return nullptr;
}
int left = 0, right = lists.size() - 1;
while (right > 0) {
if (left >= right) {
left = 0;
} else {
lists[left] = mergeTwoLists(lists[left], lists[right]);
++left;
--right;
}
}
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:
/**
* @param lists: a list of ListNode
* @return: The head of one sorted list.
*/
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:
/**
* @param lists: a list of ListNode
* @return: The head of one sorted list.
*/
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 != nullptr) {
min_heap.emplace(n);
}
}
while (!min_heap.empty()) {
// Get min of k lists.
ListNode *node = min_heap.top();
min_heap.pop();
cur->next = node;
cur = cur->next;
if (node->next != nullptr) {
min_heap.emplace(node->next);
}
}
return dummy.next;
}
};