给你一个二维整数数组 ranges 和两个整数 left 和 right 。每个 rangesi = starti, endi 表示一个从 starti 到 endi 的 闭区间 。
如果闭区间 left, right 内每个整数都被 ranges 中 至少一个 区间覆盖,那么请你返回 true ,否则返回 false 。
已知区间 rangesi = starti, endi ,如果整数 x 满足 starti <= x <= endi ,那么我们称整数x 被覆盖了。
示例 1:
输入:ranges = \[1,2,3,4,5,6], left = 2, right = 5
输出:true
解释:2 到 5 的每个整数都被覆盖了:
- 2 被第一个区间覆盖。
- 3 和 4 被第二个区间覆盖。
- 5 被第三个区间覆盖。
示例 2:
输入:ranges = \[1,10,10,20], left = 21, right = 21
输出:false
解释:21 没有被任何一个区间覆盖。
提示:
1 <= ranges.length <= 50
1 <= starti <= endi <= 50
1 <= left <= right <= 50
差分
cpp
class Solution {
public:
bool isCovered(vector<vector<int>>& ranges, int left, int right) {
int max_end = INT_MIN;
int min_start = INT_MAX;
for (auto& range : ranges) {
min_start = min(min_start, range[0]);
max_end = max(max_end, range[1]);
}
min_start = min(min_start, left);
max_end = max(max_end, right);
vector<int> diff(max_end+2);
for(auto& row : ranges){
diff[row[0]]++;
diff[row[1]+1]--;
}
int s = 0;
for(int i = min_start; i <= right; i++){
s += diff[i];
if(i >= left && s <=0){
return false;
}
}
return true;
}
};
这道题和2848相似,如果使用差分的方法做这道题,需要理解的是for(int i = min_start; i <= max_end; i++)为什么是从min_start到max_end。首先因为是差分的办法,所以i开始必须在ranges中最小的range0及其左边开始,但是由于可能会出现left在最小range0的左边,从而在遍历left到最小range0的时候满足了i>left而且s这时候又为0,会返回false。为了确保包含这种情况,我们取min_start为最小range0和left的较小值。我们定义max_end的作用就是确保row1+1和right都能在diff里不越界。当i到right的时候进行最后一次循环,因为我们的目的是找出left到right范围内的值是否有覆盖,所以遍历right以后的范围没有意义。总而言之我们需要遍历left到right的diff,但是又因为差分要保证从最小的range0即左边开始,所以在左边界取min(min_start, range[0])