AlgoMaster Logo

Smallest Range Covering Elements from K Lists

hardFrequency7 min readUpdated June 23, 2026

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. The result is like tuning a radio to the narrowest frequency band that still picks up a signal from every station.

Elements come from different lists, so a single sliding window over one array does not directly apply. We need a strategy that considers elements across all k lists at once. Any valid range must start and end at values that actually appear in the lists, since shrinking the range to a non-existent boundary only loses coverage. So the answer range [a, b] always has both a and b equal to some input element.

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 → The widest possible range is 2 * 10^5, which fits comfortably in a 32-bit integer, so range subtractions never overflow.

Approach 1: Brute Force (Check All Pairs)

Intuition

Flatten all elements into one array sorted by value (tagging each element with its list index), then try every element as the left boundary. For each left boundary, scan forward until all k lists are covered, which gives the smallest right boundary for that start. The smallest range over all starts is the answer.

The cost comes from redundant work: for each starting point we re-scan forward and rebuild 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

The wasted work is rebuilding coverage for every left boundary. A sliding window removes it by tracking coverage incrementally as the window expands and shrinks.

Approach 2: Sorting + Sliding Window

Intuition

Flatten all elements into one sorted array (keeping track of which list each came from), then slide a window that contains at least one element from every list. This is the "minimum window substring" pattern applied to sorted numbers, with list membership in place of characters. Expand the right end until all k lists are represented, then shrink from the left to minimize the range, then expand again.

Because the array is sorted, the span of any window [left, right] is sorted[right] - sorted[left]. We want to minimize that span 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), yet the input lists are already sorted individually. A min-heap reuses that structure with a k-way merge and avoids re-sorting, dropping the cost to O(n log k).

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 supports this directly. Insert one element from each list, read the current minimum at the heap top, track the current maximum separately, then 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