← DSA Atlas
Dedicated problem page · #23

Merge k Sorted Lists

HardLinked Lists and Pointer ManipulationK-way merge via min-heapMin-heap (priority queue)
Solve on LeetCode ↗
23
HardLinked Lists and Pointer ManipulationMin-heap (priority queue)K-way merge via min-heap

Merge k Sorted Lists

Given an array of k sorted linked lists, merge all of them into a single sorted linked list and return its head.

Open official problem prompt ↗
In plain English

Produce one globally sorted list from k independently sorted lists as efficiently as possible.

Picture it like this

Like a tournament where each list sends its current smallest contender; the heap referees pick the overall smallest each round and that list sends its next contender.

Example
Input
lists = [[1,4,5],[1,3,4],[2,6]]
Output
[1,1,2,3,4,4,5,6]
Why
Merging the three sorted lists produces one sorted sequence 1,1,2,3,4,4,5,6.
Constraints
k == lists.length0 <= k <= 10^40 <= lists[i].length <= 500-10^4 <= lists[i][j] <= 10^4lists[i] is sorted in ascending orderThe sum of lists[i].length does not exceed 10^4
Pattern lesson

See the pattern, then code

K-way merge via min-heap
Recognition clue

Merging many sorted sequences at once and always needing the current global minimum points to a min-heap keyed on the front elements.

Linked Lists and Pointer Manipulation

Reversal, cycle detection, merging, reordering, or O(1)-space sequence edits.. The next node of the answer is the smallest among the current heads of all k lists; a heap gives that minimum in O(log k) and lets you push the successor cheaply.

New words, made simpleKnow these before the algorithm
Min-heap
A tree structure that returns and removes the smallest element in O(log size).
Tie-breaker index
The list index stored alongside the value so equal values never force Python to compare ListNode objects.
Approaches from first idea to best ideaCompare the trade-offs
ApproachHow it thinksCost
Concatenate then sort

Discards the sortedness of each list and is slower than exploiting k << N.

Collect all N values, sort them, and rebuild a list.

Time O(N log N)Space O(N)
Merge one by one

Simple but early lists get re-scanned k times, quadratic in k.

Fold the lists together with repeated two-list merges.

Time O(N k)Space O(1)
The rule we keep true

Invariant

The heap contains exactly one node per still-active list, namely that list's smallest unconsumed value, so its top is the global minimum of all remaining nodes.

Why this is correct

Reasoning

Every node enters and leaves the heap exactly once; because each list is sorted, pushing a popped node's successor maintains one frontier node per list, guaranteeing the popped sequence is globally non-decreasing.

The algorithm in three movesSay these aloud before coding
1Push the head of every non-empty list into a min-heap keyed by value

heap heads: 1,1,2

2Pop the smallest node and append it to the result tail

pop 1(list0) -> push 4

3If the popped node has a next, push that next into the heap

pop 1(list1) -> push 3

4Repeat until the heap is empty

5Return dummy.next

Visual trace

Follow the data, one decision at a time

Input snapshotHighlighted cells are involved in this example
10
11
22
33
44
45
56
67
1 · Readheads 1,1,2
2 · AskWhat is in the heap?
3 · Update state(1,0),(1,1),(2,2)
4 · ResultReady to extract minima.
Key takeaway

The heap always holds one frontier node per list; the minimum is popped into the merged output.

Code walkthrough

Read the solution in small chunks

Python 3

Do not memorize the whole program. Connect each group of lines to one job in the algorithm.

  1. 1
    Lines 6-9Seed the heap

    Push the head of every non-empty list; the (val, i, node) tuple keeps ordering by value with i as a safe tie-breaker.

  2. 2
    Lines 10-11Result scaffold

    Dummy plus tail lets us append popped nodes in O(1).

  3. 3
    Lines 12-17Extract-and-refill loop

    Pop the minimum, attach it, and push its successor so each list keeps exactly one node in the heap.

  4. 4
    Lines 18Return

    dummy.next is the fully merged head.

Make it stick

Edge cases, mistakes, and one self-check

E

Edge cases to test

  • lists is empty (return None)
  • Some sublists are empty or None
  • All lists empty
  • A single list only
!

Common beginner mistakes

  • Pushing bare nodes without a tie-breaker causes 'ListNode not comparable' errors when values are equal
  • Forgetting to skip empty/None lists when seeding
  • Reusing tail incorrectly so the final node still points into the middle of the list (set tail = node, and the last node's next is naturally terminated because it had no successor pushed)
Check your understanding

Why is the heap size bounded by k rather than N?