The Indian Engineer

Problem 632 Smallest Range Covering Elements from K Lists

Problem Statement

Link - Problem 632

Question

You have k lists of sorted integers in non-decreasing order. Find the smallest range that includes at least one number from each of the k lists.

We define the range [a, b] is smaller than range [c, d] if b - a < d - c or a < c if b - a == d - c.

Example 1:

Input: nums = [[4,10,15,24,26],[0,9,12,20],[5,18,22,30]]
Output: [20,24]
Explanation: 
List 1: [4, 10, 15, 24,26], 24 is in range [20,24].
List 2: [0, 9, 12, 20], 20 is in range [20,24].
List 3: [5, 18, 22, 30], 22 is in range [20,24].

Example 2:

Input: nums = [[1,2,3],[1,2,3],[1,2,3]]
Output: [1,1]

Constraints:

Solution

typedef pair<int,pair<int,int>> pr;

class Solution {
public:
    vector<int> smallestRange(vector<vector<int>>& nums) {
        // Priority queue to store (value, list index, element index)
        priority_queue<pr,vector<pr>,greater<>>pq;
        int maxVal = INT_MIN, rangeStart = 0, rangeEnd = INT_MAX;

        // Insert the first element from each list into the min-heap
        for (int i = 0; i < nums.size(); i++) {
            pq.push({nums[i][0], {i, 0}});
            maxVal = max(maxVal, nums[i][0]);
        }

        // Continue until we can't proceed further
        while (pq.size() == nums.size()) {
            auto [minVal, indices] = pq.top();
            pq.pop();
            int row = indices.first, col = indices.second;

            // Update the smallest range
            if (maxVal - minVal < rangeEnd - rangeStart) {
                rangeStart = minVal;
                rangeEnd = maxVal;
            }

            // If possible, add the next element from the same row to the heap
            if (col + 1 < nums[row].size()) {
                int nextVal = nums[row][col + 1];
                pq.push({nextVal, {row, col + 1}});
                maxVal = max(maxVal, nextVal);
            }
        }

        return {rangeStart, rangeEnd};
    }
};

Complexity Analysis

| Algorithm                     | Time Complexity | Space Complexity |
| ----------------------------- | --------------- | ---------------- |
| Priority Queue Smallest Range | O(n log k)      | O(k)             |

Explanation

Intial Thoughts

To solve this problem, we should first consider how to compare ranges and determine which one is smaller. We should also think about how to efficiently select numbers from each list to minimize the range. Key points include understanding the definition of a smaller range, recognizing the need to track the maximum value seen so far, and realizing the importance of using a data structure like a priority queue to efficiently select the smallest number from the current options in each list. Additionally, we should consider how to update the smallest range as we process numbers from each list. We need to identify the conditions under which we update the range and ensure that we stop when we can no longer make progress.

Intuitive Analysis

Intuitively, solving this problem involves maintaining a balance between minimizing the range and ensuring that we include at least one number from each list. This can be achieved by always selecting the smallest available number from the lists and then updating the range if necessary. We should imagine the process as a continuous selection and updating process, where we keep track of the maximum value seen and the current smallest range. The use of a priority queue helps in making this selection process efficient by always giving us the smallest number to consider next. By thinking about the problem in this way, we can develop an algorithm that efficiently finds the smallest range.

1. Intuition

2. Implementation


Complexity Analysis

Time Complexity:

Space Complexity:


Footnote

This question is rated as Hard difficulty.


Similar Questions:

Title URL Difficulty
Minimum Window Substring https://leetcode.com/problems/minimum-window-substring Hard