Reputation: 375
def merge(list1, list2):
results = []
while list1 and list2:
if list1[0] < list2[0]:
results.append(list1.pop(0))
else:
results.append(list2.pop(0))
results.extend(list1)
results.extend(list2)
return results
Here is the standard algorithm to merge 2 sorted lists into 1. However, how can we merge multiple sorted lists into 1?
l = [[8, 10, 12], [4, 5, 9], [2, 11]]
merge(l)
>>> [2, 4, 5, 8, 9, 10, 11, 12]
Upvotes: 0
Views: 2326
Reputation: 3416
An easy and efficient way is heapq.merge:
>>> lists = [[8, 10, 12], [4, 5, 9], [2, 11]]
>>> list(heapq.merge(*lists))
[2, 4, 5, 8, 9, 10, 11, 12]
Glancing at CPython's implementation, it looks similar to the direct k-way merge answer, so I would guess that heapq.merge
is O(n log(k))
as well, though the docstring does not guarantee this.
Upvotes: 1
Reputation: 153
from Queue import PriorityQueue
class Solution(object):
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
head = point = ListNode(0)
q = PriorityQueue()
for l in lists:
if l:
q.put((l.val, l))
while not q.empty():
val, node = q.get()
point.next = ListNode(val)
point = point.next
node = node.next
if node:
q.put((node.val, node))
return head.next
Using a Priority Queue optimizes the comparison process
Time Complexity: O(n log(k)) where k is the number of linked lists:
Space Complexity:
Upvotes: 0
Reputation: 4606
Flatten with list comprehension and then sort
print(sorted([j for i in l for j in i]))
# [2, 4, 5, 8, 9, 10, 11, 12]
Upvotes: 0
Reputation: 12990
You can use your own merge
with reduce
:
from functools import reduce
l = [[8, 10, 12], [4, 5, 9], [2, 11]]
merged = reduce(merge, l)
print(merged)
# [2, 4, 5, 8, 9, 10, 11, 12]
This has running time O(kn). You could merge (unique) pairs until you have 1 final list left, which would improve it to O(n log k) (as the number of lists to merge reduces by half every time).
Upvotes: 2
Reputation: 61910
You could implement direct k-way merge using a heap and queues:
import heapq
from collections import deque
def k_merge(*lists):
queues = [queue for queue in map(deque, lists)]
heap = []
for i, lst in enumerate(queues):
heap.append((lst.popleft(), i))
heapq.heapify(heap)
result = []
while heap:
value, index = heapq.heappop(heap)
result.append(value)
if queues[index]:
heapq.heappush(heap, (queues[index].popleft(), index))
return result
print(k_merge(*[[8, 10, 12], [4, 5, 9], [2, 11]]))
Output
[2, 4, 5, 8, 9, 10, 11, 12]
If you have k
lists and n
elements this approach is O(nlogk)
Upvotes: 4
Reputation: 7510
You can just sort it using sorted()
:
from itertools import chain
l = [[8, 10, 12], [4, 5, 9], [2, 11]]
sorted(chain(*l))
Gives result:
[2, 4, 5, 8, 9, 10, 11, 12]
Upvotes: 2