Skip to content

Merge k Sorted Lists

You are given an array of k linked-lists lists, each linked-list is sorted in ascending order.

Merge all the linked-lists into one sorted linked-list and return it.

InputOutput
[[1,4,5],[1,3,4],[2,6]]1→1→2→3→4→4→5→6
[]null
[[]]null
  • k == lists.length
  • 0 <= k <= 10^4
  • 0 <= lists[i].length <= 500
  • -10^4 <= lists[i][j] <= 10^4
ApproachTimeSpace
Recursive Divide & ConquerO(nk log k)O(log k)
Min HeapO(nk log k)O(k)

n = total nodes across all lists

  • Pick Divide & Conquer for pattern clarity — mirrors merge sort.
  • Pick Min Heap for intuitive greedy selection of smallest.
Pattern Match
Divide & Conquer
O(nk log k) time · O(log k) space
Greedy Pick
Min Heap
O(nk log k) time · O(k) space
Section titled “Approach 1: Recursive Divide and Conquer (Recommended)”
★ Recommended
  1. Recursively split lists in half.
  2. Merge each pair of resulting lists.
  3. Base case: single list or empty range.

The key insight: merging k lists pairwise is O(log k) levels, each level does O(nk) work → O(nk log k) total.

⏱ Time O(nk log k) Divide and conquer 💾 Space O(log k) Recursion depth
merge_k_sorted_lists_recursive.py
from typing import Optional, List
import heapq
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeKLists(lists: List[Optional[ListNode]]) -> Optional[ListNode]:
if not lists:
return None
def merge(l1, l2):
dummy = ListNode(0)
curr = dummy
while l1 and 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 if l1 else l2
return dummy.next
def partition(lists, left, right):
if left == right:
return lists[left]
if left > right:
return None
mid = (left + right) // 2
l1 = partition(lists, left, mid)
l2 = partition(lists, mid + 1, right)
return merge(l1, l2)
return partition(lists, 0, len(lists) - 1)
# Example
l1 = ListNode(1, ListNode(4, ListNode(5)))
l2 = ListNode(1, ListNode(3, ListNode(4)))
l3 = ListNode(2, ListNode(6))
result = mergeKLists([l1, l2, l3])
while result:
print(result.val, end=" ")
result = result.next
🎯 Interview Favourite
  1. Push all list heads into a min-heap.
  2. Repeatedly extract the smallest, append to result, and push its next node.
  3. Stop when heap is empty.
⏱ Time O(nk log k) Each node processed once, heap ops 💾 Space O(k) Heap storage
merge_k_sorted_lists_heap.py
from typing import Optional, List
import heapq
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
def mergeKLists(lists: List[Optional[ListNode]]) -> Optional[ListNode]:
dummy = ListNode(0)
curr = dummy
heap = []
for i, lst in enumerate(lists):
if lst:
heapq.heappush(heap, (lst.val, i, lst))
while heap:
val, idx, node = heapq.heappop(heap)
curr.next = node
curr = curr.next
if node.next:
heapq.heappush(heap, (node.next.val, idx, node.next))
return dummy.next
# Example
l1 = ListNode(1, ListNode(4, ListNode(5)))
l2 = ListNode(1, ListNode(3, ListNode(4)))
l3 = ListNode(2, ListNode(6))
result = mergeKLists([l1, l2, l3])
while result:
print(result.val, end=" ")
result = result.next
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
merge_k_sorted_lists_space_optimized.py
"""
Solution for Merge k Sorted Lists
"""
def solve():
"""Implementation for approach 3 of Merge k Sorted Lists"""
pass
if __name__ == "__main__":
print("Solution ready")