-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMerge k Sorted Lists.cpp
More file actions
95 lines (89 loc) · 3.4 KB
/
Merge k Sorted Lists.cpp
File metadata and controls
95 lines (89 loc) · 3.4 KB
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
/* Method 1: using priority_queue n: length of lists, m: average length of each linked list
* Space Complexity: O(n)
* Time complexity (access + deletion + insertion): O(n * m) * (O(1) + 2 * O(logn)) -> O(n * m) O(logn) if(m small), O(n logn)
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
struct compare{
bool operator()(const ListNode* n1, const ListNode* n2) const {
return n1->val > n2->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<ListNode*, vector<ListNode*>, compare> pq; // define a priority_queue where the nodes with smaller values come first;
// push the head of all the lists into the heap;
for (auto ln : lists) {
if (ln != nullptr) {
pq.push(ln);
}
}
// a dummy node whose next pointer is the head of the new linkedlist;
ListNode* d = new ListNode(0);
// c is the pointer of the current node
ListNode* c = d;
// As long as the heap is non-empty, pop the nodes at the top, and let it be the next pointer of the current node c;
// Meanwhile, push the next pointer of the nodes that poped out (if the next pointer is not a nullptr);
while (!pq.empty()) {
ListNode* temp = pq.top();
pq.pop();
c->next = temp;
if (temp->next) {
pq.push(temp->next);
}
c = c->next;
}
// we reach the end of the list, so we let current node c point to a nullptr; and return d->next;
c->next = nullptr;
return d->next;
}
};
/* Method 2: using multimap
* Space complexity: O(n)
* Time complexity: (access + erase + insertion) O(n * m) * (O(1) + O(1) + O(logn)) -> O(n * m) O(logn) if(m small), O(n logn)
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
multimap<int, ListNode*> mp; // a multimap with the value as the key and iterator as the value;
// push the head of all the lists into the map;
for (auto l : lists) {
if (l != nullptr) mp.insert(make_pair(l->val, l));
}
// d is a dummy node whose next pointer if the head of the new linked list;
ListNode* d = new ListNode(0);
ListNode* c = d; // c is the current point;
// // As long as the map is non-empty, erase the element at the top,
//and let its value the next pointer of the current node c;
// Meanwhile, push the next pointer of the nodes that erased
// (if the next pointer is not a nullptr);
while (!mp.empty()) {
auto it = mp.begin();
ListNode* temp = it->second;
mp.erase(it);
c->next = temp;
if (temp->next) {
mp.insert(make_pair(temp->next->val, temp->next));
}
c = c->next;
}
// we reach the end of the list, so we let current node c point to a nullptr; and return d->next;
c->next = nullptr;
return d->next;
}
};