LeetCode 632. 最小区间(排序+滑动窗口)

文章目录

    • 1. 题目
    • 2. 解题

1. 题目

你有 k 个升序排列的整数数组。
找到一个最小区间,使得 k 个列表中的每个列表至少有一个数包含在其中。

我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < c,则区间 [a,b] 比 [c,d] 小。

示例 1:
输入:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
输出: [20,24]
解释: 
列表 1[4, 10, 15, 24, 26]24 在区间 [20,24] 中。
列表 2[0, 9, 12, 20]20 在区间 [20,24] 中。
列表 3[5, 18, 22, 30]22 在区间 [20,24] 中。

注意:
给定的列表可能包含重复元素,所以在这里升序表示 >=1 <= k <= 3500
-10^5 <= 元素的值 <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/smallest-range-covering-elements-from-k-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

  • 把数字和其区间的编号,存入vector,并排序
  • 滑动窗口方法,保证窗口内有 k 个区间的数,记录最小差的左右端点值
class Solution {
public:
    vector<int> smallestRange(vector<vector<int>>& nums) {
    	vector<vector<int>> v;
    	int k = nums.size();
    	for(int i = 0; i < nums.size(); ++i)
    	{
    		for(int n : nums[i])
    			v.push_back({n,i});//num, 区间编号
    	}
    	sort(v.begin(), v.end());
    	unordered_map<int,int> m;//区间编号,该区间有多少个数在窗口内
    	int i = 0, j = 0, n = v.size();
    	int l = -1e7, r = 1e7;
    	while(j < n)
    	{
    		if(m.size() < k)
    			m[v[j][1]]++;
    		while(m.size() == k)
    		{
    			if(v[j][0]-v[i][0] < r-l)
    			{
    				l = v[i][0];
    				r = v[j][0];
    			}
    			if(--m[v[i][1]] == 0)
    				m.erase(v[i][1]);
    			i++;
    		}
            j++;
    	}
    	return {l, r};
    }
};

496 ms 24.5 MB


我的CSDN博客地址 https://michael.blog.csdn.net/

长按或扫码关注我的公众号(Michael阿明),一起加油、一起学习进步!
Michael阿明

你可能感兴趣的:(LeetCode)