Solution: Smallest Range Covering Elements from K Lists
Let’s solve the Smallest Range Covering Elements from K Lists problem using the Top K Elements pattern.
We'll cover the following
Statement
You are given nums
, where each list in nums
is in non-decreasing order. Your task is to find the smallest range that contains at least one element from each of the
A range
Constraints:
nums.length
nums[i].length
nums[i][j]
nums[i]
is sorted in a non-decreasing order.
Solution
The core idea of this solution is to find the smallest range that includes at least one number from each of the k sorted lists. Instead of generating all possible ranges across the lists, the solution uses a min heap (priority queue) to dynamically track the smallest and largest values across currently considered elements. This approach ensures that at every step, the solution maintains a potential valid range that includes one element from each list, continuously narrowing it down to the smallest possible.
The process begins by initializing a min heap (priority queue) and pushing the first element from each list into it. Along with each value, the index of the list it belongs to and its position within it are also stored in the heap. Additionally, a variable, maxVal
, is maintained to keep track of the current maximum number among the values present in the heap. This is important because, at any point, the smallest range that covers all lists is defined by the current smallest and largest elements among the chosen set.
Once the heap is initialized, the solution enters a loop that continues as long as the heap contains one element from each list (i.e., the length of the heap equals the number of lists). In each iteration, the smallest value is popped from the heap — this represents the lower bound of the current candidate range. The result is updated accordingly if the current range (maxVal - minVal
) is smaller than the previously recorded best range.
To maintain the invariant that the heap contains one element from each list, the next element from the list of the popped value is pushed into the heap. While doing so, maxVal
is updated if the newly pushed element is larger than the current maximum. This ensures that the next potential range still includes one element from every list and remains as small as possible.
This process continues until it’s no longer possible to push the next element from one of the lists (i.e., the shortest list is exhausted). At that point, the smallest valid range is guaranteed to be identified and stored.
Let’s break down the key steps of the solution:
We initialize the following:
A min heap
pq
to store tuples of the form.maxVal
to track the maximum of the current elements from all lists.rangeStart
andrangeEnd
to store the current smallest range.
We push the first elements of each list to the heap, and
maxVal
is updated to the maximum of all these first elements.We iterate while the heap contains one element from each list:
Pop the smallest value (
minVal
) from the heap.If the range formed by
minVal
andmaxVal
is smaller than the previous best, updaterangeStart
andrangeEnd
.If the next element exists in the list from which
minVal
was popped, push it into the heap, and updatemaxVal
if needed.
We stop iterating once one of the lists runs out of elements.
The final smallest range covering at least one element from each list is returned as
[rangeStart, rangeEnd]
.
Let’s look at the following illustration to get a better understanding of the solution:
Level up your interview prep. Join Educative to access 70+ hands-on prep courses.