AlgoMaster Logo

Smallest Range Covering Elements from K Lists

Last Updated: April 4, 2026

hard
4 min read

Understanding the Problem

We're given k sorted lists and need to find the tightest window (smallest range) such that at least one element from every list falls inside that window. Think of it like tuning a radio dial: you need to find the narrowest frequency band where you can pick up a signal from every station.

The tricky part is that elements come from different lists, so we can't just use a simple sliding window on a single array. We need a strategy that considers elements across all k lists simultaneously. The key observation is that any valid range must start and end at elements that actually appear in the lists. So the answer range [a, b] always has a and b as values from the input.

Key Constraints:

  • 1 <= k <= 3500 and 1 <= nums[i].length <= 50 → The total number of elements across all lists is at most 175,000. This is manageable for O(n log n) or O(n log k) approaches.
  • nums[i] is sorted in non-decreasing order → Each list is already sorted. We can exploit sorted order with pointers or a min-heap to process elements in order.
  • -10^5 <= nums[i][j] <= 10^5 → Standard comparison-based methods are the way to go.

Approach 1: Brute Force (Check All Pairs)

Intuition

The most direct approach: flatten all elements into a sorted array (tagged with their list index), then for each possible starting element, expand outward until all k lists are covered. This is essentially trying every element as the left boundary of the range and finding the smallest right boundary that covers all lists.

This approach is straightforward but involves redundant work. For each starting point, we re-scan forward to build coverage from scratch.

Algorithm

  1. Flatten all elements from all lists into a single list, tagging each with its list index.
  2. Sort this combined list by value.
  3. For each starting index i, scan forward with index j until all k lists have at least one element in the window [i, j].
  4. Record the range [sorted[i], sorted[j]] if it's smaller than the current best.
  5. Return the best range found.

Example Walkthrough

1Sorted elements: (0,L2),(4,L1),(5,L3),(9,L2),(10,L1),(12,L2),(15,L1),(18,L3),(20,L2),(22,L3),(24,L1),(26,L1),(30,L3)
0
0
1
4
2
5
3
9
4
10
5
12
6
15
7
18
8
20
9
22
10
24
11
26
12
30
1/7

Code

For each starting index, we rebuild the coverage set from scratch. What if we maintained a sliding window instead, keeping track of which lists are covered as we expand and shrink?

Approach 2: Sorting + Sliding Window

Intuition

Here's the key insight: flatten all elements into one sorted array (keeping track of which list each came from), then use a sliding window to find the smallest window that contains at least one element from every list.

This is essentially the "minimum window substring" pattern but applied to sorted numbers with list membership instead of characters. We expand the right end of the window until all k lists are represented, then shrink from the left to minimize the range, then expand again.

Because the array is sorted, the range of any window [left, right] is simply sorted[right] - sorted[left]. We want to minimize this while covering all k lists.

Algorithm

  1. Flatten all elements into a list of (value, listIndex) pairs and sort by value.
  2. Use two pointers, left and right, both starting at 0.
  3. Maintain a frequency map counting how many elements from each list are in the current window, and a counter for how many distinct lists are covered.
  4. Expand right until all k lists are covered.
  5. Once all k lists are covered, try shrinking from left to minimize the range. Update the best range if the current one is smaller.
  6. Continue until right reaches the end.

Example Walkthrough

1Initialize: left=0, right=0. Labels: (L2),(L1),(L3),(L2),(L1),(L2),(L1),(L3),(L2),(L3),(L1),(L1),(L3)
0
left
0
right
1
4
2
5
3
9
4
10
5
12
6
15
7
18
8
20
9
22
10
24
11
26
12
30
1/7

Code

The sorting step dominates at O(n log n), but the input lists are already sorted individually. What if we leveraged that sorted structure with a min-heap to avoid re-sorting entirely?

Approach 3: Min-Heap (Optimal)

Intuition

Since each list is already sorted, we can think of this as a k-way merge problem. Start by picking the first element from each list. These k elements define an initial range from min to max. Now, to try to shrink the range, we have two choices: increase the min or decrease the max.

Decreasing the max isn't useful because we'd need to go backward in a sorted list, which would only make the range larger or keep it the same. But increasing the min makes sense: we advance the pointer in the list that contributed the current minimum to its next element. This gives us a new candidate minimum, and the range might shrink.

A min-heap is perfect for this. We insert one element from each list, always know the current minimum (heap top), track the current maximum separately, and repeatedly pop the minimum and push its successor from the same list.

Algorithm

  1. Initialize a min-heap with the first element from each list, tracking (value, listIndex, elementIndex).
  2. Track the current maximum across all elements in the heap.
  3. The current range is [heap_top, currentMax].
  4. Pop the minimum element. If its range is better than the best seen, update the result.
  5. Push the next element from the same list (if it exists). Update currentMax if needed.
  6. Stop when any list is exhausted (we can't cover all k lists anymore).

Example Walkthrough

1Init: heap=[0(L2), 4(L1), 5(L3)], currentMax=5, range=[0,5], best=[0,5]
0
min
0
1
4
2
5
max
1/8

Code