Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Merge k Sorted Lists in Python
Merging k sorted lists is a classic algorithm problem. Given multiple sorted linked lists, we need to combine them into a single sorted list. Python's heapq module provides an efficient solution using a min-heap data structure.
Problem Understanding
Given k sorted linked lists like [1,4,5], [1,3,4], [2,6], we need to merge them into one sorted list [1,1,2,3,4,4,5,6].
Algorithm Steps
Create a min-heap to store the smallest elements from each list
Add the first node of each non-empty list to the heap
Repeatedly extract the minimum element from the heap
Add the next node from the same list (if exists) back to the heap
Continue until the heap is empty
Using Python's heapq Module
import heapq
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def __lt__(self, other):
return self.val < other.val
def merge_k_lists(lists):
heap = []
# Add first node of each non-empty list to heap
for i, node in enumerate(lists):
if node:
heapq.heappush(heap, node)
dummy = ListNode(0)
current = dummy
while heap:
# Extract minimum node
min_node = heapq.heappop(heap)
current.next = min_node
current = current.next
# Add next node from same list to heap
if min_node.next:
heapq.heappush(heap, min_node.next)
return dummy.next
# Helper function to create linked list from array
def create_list(arr):
if not arr:
return None
head = ListNode(arr[0])
current = head
for val in arr[1:]:
current.next = ListNode(val)
current = current.next
return head
# Helper function to print linked list
def print_list(head):
result = []
while head:
result.append(head.val)
head = head.next
return result
# Example usage
lists_data = [[1,4,5], [1,3,4], [2,6]]
linked_lists = [create_list(arr) for arr in lists_data]
merged = merge_k_lists(linked_lists)
print(print_list(merged))
[1, 1, 2, 3, 4, 4, 5, 6]
Alternative Approach: Divide and Conquer
def merge_two_lists(l1, l2):
dummy = ListNode(0)
current = dummy
while l1 and l2:
if l1.val <= l2.val:
current.next = l1
l1 = l1.next
else:
current.next = l2
l2 = l2.next
current = current.next
current.next = l1 or l2
return dummy.next
def merge_k_lists_divide_conquer(lists):
if not lists:
return None
while len(lists) > 1:
merged_lists = []
# Merge lists in pairs
for i in range(0, len(lists), 2):
l1 = lists[i]
l2 = lists[i + 1] if i + 1 < len(lists) else None
merged_lists.append(merge_two_lists(l1, l2))
lists = merged_lists
return lists[0]
# Example usage
lists_data = [[1,4,5], [1,3,4], [2,6]]
linked_lists = [create_list(arr) for arr in lists_data]
merged = merge_k_lists_divide_conquer(linked_lists)
print(print_list(merged))
[1, 1, 2, 3, 4, 4, 5, 6]
Time Complexity Comparison
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Min-Heap | O(n log k) | O(k) |
| Divide & Conquer | O(n log k) | O(1) |
Where n is the total number of nodes and k is the number of lists.
Conclusion
Both approaches efficiently merge k sorted lists with O(n log k) time complexity. The heap approach is intuitive and easy to implement, while divide-and-conquer uses less extra space. Choose based on your specific requirements and constraints.
