Merge k Sorted Lists

Hard Heaps Merge K Sorted Original on LeetCode

Merge k Sorted Lists is a hard heaps problem solved with the merge k sorted pattern. The best approach, optimal (min-heap of heads), runs in O(N log k) time and O(k) space. Below are 2 approaches in Java, from merge one list at a time up.

Problem

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

Examples

Example 1

Input
lists = [[1, 4, 5], [1, 3, 4], [2, 6]]
Output
[1, 1, 2, 3, 4, 4, 5, 6]

Example 2

Input
lists = [[], []]
Output
[]

Constraints

  • 0 <= k <= 10^4; total nodes N up to 10^4.
  • Each list is sorted.

Animated walkthrough

A narrated, step-by-step animation that builds the solution from the idea up. Press play, or step through it at your own pace.

Concepts first, then the problem and every approach, step by step.

Space to play or pause · ← → to jump a step · click or drag the bar to seek

Solutions

Try it yourself first. Then compare: each approach lists its idea, the steps, its time and space, and the Java code.

ApproachTimeSpace
Merge one list at a timeO(k · N)O(1)
Optimal (min-heap of heads)O(N log k)O(k)

1Merge one list at a time

TimeO(k · N)The growing result is re-walked for every list.
SpaceO(1)

Merge list 0 with list 1, then the result with list 2, and so on.

  1. result = null; for each list: result = mergeTwo(result, list).
Java
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        ListNode result = null;
        for (ListNode l : lists) result = merge(result, l);
        return result;
    }

    private ListNode merge(ListNode a, ListNode b) {
        ListNode dummy = new ListNode(), t = dummy;
        while (a != null && b != null) {
            if (a.val <= b.val) { t.next = a; a = a.next; } else { t.next = b; b = b.next; }
            t = t.next;
        }
        t.next = a != null ? a : b;
        return dummy.next;
    }
}

2Optimal (min-heap of heads)

TimeO(N log k)
SpaceO(k)

Put the head of each non-empty list in a min-heap. Repeatedly poll the smallest, append it, and push its next node.

  1. Offer all non-null heads.
  2. While the heap is not empty: n = poll(); tail.next = n; if n.next != null offer(n.next).
Java
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        PriorityQueue<ListNode> heap = new PriorityQueue<>((a, b) -> Integer.compare(a.val, b.val));
        for (ListNode l : lists) if (l != null) heap.offer(l);
        ListNode dummy = new ListNode(), tail = dummy;
        while (!heap.isEmpty()) {
            ListNode n = heap.poll();
            tail.next = n;
            tail = n;
            if (n.next != null) heap.offer(n.next);
        }
        return dummy.next;
    }
}

Edge cases to test

  • Empty lists inside the array
  • k = 0

Hints

Hint 1

The next node of the answer is always the smallest current head. A min-heap finds it in O(log k).

FAQ

What is the best time complexity for Merge k Sorted Lists?

Optimal (min-heap of heads) runs in O(N log k) time and O(k) extra space.

Which pattern does Merge k Sorted Lists use?

It is a heaps problem that uses the merge k sorted pattern. Other problems with the same pattern: Merge k Sorted Arrays.

Is there a brute force solution for Merge k Sorted Lists?

Yes. Merge one list at a time takes O(k · N) time and O(1) space. Merge list 0 with list 1, then the result with list 2, and so on.

Which edge cases should I test for Merge k Sorted Lists?

Empty lists inside the array; k = 0.