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:
- The given list may contain duplicates, so ascending order means >= here.
- 1 <=
k
<= 3500 - -105 <=
value of elements
<= 105. - For Java users, please note that the input type has been changed to List<List<Integer>>. And after you reset the code template, you'll see this poin。
你有 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
-105 <= 元素的值 <= 105
对于使用Java的用户,请注意传入类型已修改为List<List<Integer>>。重置代码模板后可以看到这项改动。
解题思路:
类似于76. Minimum Window Substring 最小窗口子串
class Solution {
public:
vector<int> smallestRange(vector<vector<int>>& nums)
{
vector<pair<int , int >> merge ;
vector<int> res ;
for(int i = 0 ; i < nums.size() ; ++i)
{
for(auto num : nums[i])
{
merge.push_back({num , i});
}
}
sort(merge.begin() , merge.end()) ;
int i = 0 , j = 0 , cnt = 0 , k = nums.size() ;
unordered_map<int , int > ans ;
for(; j < merge.size() ; j++)
{
if(++ans[merge[j].second] == 1) cnt++ ;
while(cnt == k)
{
if(res.empty() || merge[j].first - merge[i].first < res[1] - res[0] || (merge[j].first - merge[i].first == res[1] - res[0] && merge[i].first < res[0]))
{
res = { merge[i].first , merge[j].first} ;
}
if(--ans[merge[i].second] < 1) cnt-- ;
++i ;
}
}
return res ;
}
};
class Solution {
public:
vector<int> smallestRange(vector<vector<int>>& nums)
{
if(nums.empty()) return {} ;
vector<pair<int,int>> num_group ;
for(int i = 0 ; i < nums.size() ; ++i)
for(int j = 0 ; j < nums[i].size() ; ++j)
num_group.push_back({nums[i][j] , i}) ;
sort(begin(num_group) , end(num_group)) ;
unordered_map<int , int> groups ;
vector<int> res ;
int i_start = 0 , i_end = 0 ;
groups[num_group[0].second]++ ;
while(i_start <= i_end && i_end < num_group.size() )
{
if(groups.size() == nums.size())
{
if(res.empty())
{
res = {num_group[i_start].first , num_group[i_end].first} ;
}
else
{
if(num_group[i_end].first - num_group[i_start].first < res[1] - res[0])
res = {num_group[i_start].first , num_group[i_end].first} ;
else if(num_group[i_end].first - num_group[i_start].first == res[1] - res[0] && num_group[i_start].first < res[0])
res = {num_group[i_start].first , num_group[i_end].first} ;
}
groups[num_group[i_start].second]--;
if(groups[num_group[i_start].second] == 0) groups.erase(num_group[i_start].second) ;
i_start++;
}
else
{
i_end++; //因为i_end先加,所以while条件设置成i_end < num_group.size() - 1,这还是不行。
if(i_end < num_group.size()) groups[num_group[i_end].second]++;//最好是在这里加个判断;
}
}
return res ;
}
};