Merge k Sorted Lists
Picture
Lists [1,4], [2,3], and [0,7] each expose their smallest remaining value.
Predict
After popping one node, which list can offer a newly eligible node?
Walk through the small example
Only that node’s list. Each sorted source needs only one representative in the priority frontier.
Mental model and complete Python solution
Every hidden item is at least the visible front of its own list. Therefore the global minimum must be among the k visible fronts.
What the function promises: Return one sorted chain reusing nodes from disjoint, acyclic, sorted lists.
class Node:
def __init__(self, value, next_node=None):
self.value, self.next = value, next_node
def build(values):
head = None
for value in reversed(values):
head = Node(value, head)
return head
def to_list(head):
answer = []
while head is not None:
answer.append(head.value)
head = head.next
return answer
from heapq import heappush, heappop
def merge_k_lists(lists):
heap = []
sequence = 0
for node in lists:
if node is not None:
heappush(heap, (node.value, sequence, node))
sequence += 1
dummy = tail = Node(None)
while heap:
_, _, node = heappop(heap)
tail.next = node
tail = node
if node.next is not None:
heappush(heap, (node.next.value, sequence, node.next))
sequence += 1
return dummy.next
assert to_list(merge_k_lists([build([1,4]),build([2,3]),build([0,7])])) == [0,1,2,3,4,7]
assert merge_k_lists([]) is None
Work and storage: O(N log k) time and O(k) heap space for N total nodes.
When to recognize it: Each sorted source needs only one representative in the priority frontier.
Check before applying it: Heap entries need a deterministic tiebreaker because linked nodes are not inherently comparable.
Change one rule
The sources are remote streams that may fail.
See what changes
Keep cursor and retry state per source; the heap algorithm alone does not define delivery or consistency.
Connect
Merge two sorted linked lists: Two fronts generalize to k fronts.
Heap: keep the next extreme ready: The heap exposes the smallest waiting front.