632. Smallest Range

632. Smallest Range

  • 方法1: priority_queue
    • 易错点:
    • Complexity

You have k lists of sorted integers in ascending 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:[[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].

Note:

  1. The given list may contain duplicates, so ascending order means >= here.
  2. 1 <= k <= 3500
  3. -105 <= value of elements <= 105.
  4. For Java users, please note that the input type has been changed to List.
  5. And after you reset the code template, you’ll see this point.

方法1: priority_queue

官方题解:https://leetcode.com/problems/smallest-range/solution/

思路:

官方题解第三种方法将思路讲的很清楚。首先我们每个stream取一个点,确定了min 和 max,也有了range,接下来如何缩小range?max现在不能减小,所以选择增大min。找到min所在的stream,向前推进一个,再次比较找到新的min,和max。注意,这个找min和max的过程如果用pointer的方法,需要O(k),但是如果用priority queue,只需要o(logk)。对于min我们需要知道取到最小以后,如何向前推进,所以还要同时记录该数字来自哪条stream,以及它当前所处的index。在这里将{num , i} 组成pair存在pq里一起排序,而用一个k长度的vector记录每条steam行进到的index。其他的方法还可能使用iterator。对于max来讲,每一次我们并不会直接推进,而是被动的被下一次pop出来的数字不断向上拉,所以用一个int mx,来max(mx,newpopped)就可以。

易错点:

  1. 当任何一条stream结束之后,搜索可以结束。

Complexity

Time complexity: O(n log k)
Space complexity: O(k)

class Solution {
public:
    vector smallestRange(vector>& nums) {
        priority_queue, vector>, greater>> q;
         int k = nums.size();
        vector result(2, 0);
        vector pt(k, 0);
        int mx = INT_MIN;
        int range = INT_MAX;
       
        
        for (int i = 0; i < k; i++) {
            //if (nums[i].empty()) return {};
            q.push({nums[i][0], i});
            mx = max(mx, nums[i][0]);
        }
    
        while (true) {
            int mn = q.top().first;
            int i = q.top().second;
            q.pop();
           
            if (mx - mn < range) {
                range = mx - mn;
                result[0] = mn;
                result[1] = mx;
            }
            
            if (pt[i] == nums[i].size() - 1) break;
            
            pt[i]++;
            mx = max(mx, nums[i][pt[i]]);
            q.push({nums[i][pt[i]], i});
        }
        return result;
    }
};

你可能感兴趣的:(632. Smallest Range)