Find K Pairs with Smallest Sums

Medium Heaps Advanced Original on LeetCode

Find K Pairs with Smallest Sums is a medium heaps problem solved with the advanced pattern. The best approach, optimal (heap frontier, like merging k lists), runs in O(k log k) time and O(k) space. Below are 2 approaches in Java, from all pairs into a heap up.

Problem

Given two sorted arrays and k, return the k pairs (u, v) (one value from each array) with the smallest sums u + v.

Examples

Example 1

Input
nums1 = [1, 7, 11], nums2 = [2, 4, 6], k = 3
Output
[[1,2],[1,4],[1,6]]

Example 2

Input
nums1 = [1, 1, 2], nums2 = [1, 2, 3], k = 2
Output
[[1,1],[1,1]]

Constraints

  • 1 <= nums1.length, nums2.length <= 10^5; both sorted ascending.
  • 1 <= k <= 10^4 and k <= the total number of pairs.

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
All pairs into a heapO(m · n · log k)O(k)
Optimal (heap frontier, like merging k lists)O(k log k)O(k)

1All pairs into a heap

TimeO(m · n · log k)
SpaceO(k)

Generate every pair, keep a max-heap of size k, then output the heap.

  1. For each i, j: offer; poll when the size exceeds k.
Java
class Solution {
    public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> Integer.compare(b[0] + b[1], a[0] + a[1]));
        for (int x : nums1)
            for (int y : nums2) {
                heap.offer(new int[] { x, y });
                if (heap.size() > k) heap.poll();
            }
        List<List<Integer>> out = new ArrayList<>();
        while (!heap.isEmpty()) { int[] p = heap.poll(); out.add(0, Arrays.asList(p[0], p[1])); }
        return out;
    }
}

2Optimal (heap frontier, like merging k lists)

TimeO(k log k)
SpaceO(k)

Seed the heap with (i, 0) for the first min(k, m) rows. Each time you poll (i, j), push (i, j + 1), the next pair in that row. The heap never holds more than k entries, and you stop after k polls.

  1. Offer {nums1[i] + nums2[0], i, 0} for i < min(k, m).
  2. Repeat k times: poll {sum, i, j}; record the pair; if j + 1 < n, offer (i, j + 1).
Java
class Solution {
    public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
        PriorityQueue<int[]> heap = new PriorityQueue<>((a, b) -> Integer.compare(a[0], b[0]));
        for (int i = 0; i < Math.min(k, nums1.length); i++) heap.offer(new int[] { nums1[i] + nums2[0], i, 0 });
        List<List<Integer>> out = new ArrayList<>();
        while (k-- > 0 && !heap.isEmpty()) {
            int[] e = heap.poll();
            int i = e[1], j = e[2];
            out.add(Arrays.asList(nums1[i], nums2[j]));
            if (j + 1 < nums2.length) heap.offer(new int[] { nums1[i] + nums2[j + 1], i, j + 1 });
        }
        return out;
    }
}

Edge cases to test

  • k larger than one array's length
  • Duplicate values

Hints

Hint 1

Picture a matrix where cell (i, j) = nums1[i] + nums2[j]. Rows and columns are sorted, so it is like merging k sorted lists.

FAQ

What is the best time complexity for Find K Pairs with Smallest Sums?

Optimal (heap frontier, like merging k lists) runs in O(k log k) time and O(k) extra space.

Which pattern does Find K Pairs with Smallest Sums use?

It is a heaps problem that uses the advanced pattern.

Is there a brute force solution for Find K Pairs with Smallest Sums?

Yes. All pairs into a heap takes O(m · n · log k) time and O(k) space. Generate every pair, keep a max-heap of size k, then output the heap.

Which edge cases should I test for Find K Pairs with Smallest Sums?

k larger than one array's length; Duplicate values.