《LeetCode之每日一题》:100.检查是否区域内所有整数都被覆盖
Posted 是七喜呀!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《LeetCode之每日一题》:100.检查是否区域内所有整数都被覆盖相关的知识,希望对你有一定的参考价值。
题目链接: 检查是否区域内所有整数都被覆盖
有关题目
给你一个二维整数数组 ranges 和两个整数 left 和 right 。
每个 ranges[i] = [starti, endi] 表示一个从 starti 到 endi 的 闭区间 。
如果闭区间 [left, right] 内每个整数都被 ranges 中
至少一个 区间覆盖,那么请你返回 true ,否则返回 false 。
已知区间 ranges[i] = [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
题解
法一:暴力法
bool isCovered(int** ranges, int rangesSize, int* rangesColSize, int left, int right){
int check[51];//51为[1,50]
memset(check, 0, sizeof(check));
for (int i = 0; i < rangesSize; i++)
{
for (int j = ranges[i][0]; j <= ranges[i][1]; j++)
check[j] = 1;//标记[l,r]出现区域
}
for (int i = left; i <= right; i++)
if (check[i] == 0) return false;
return true;
}
法二:排序
class Solution {
public:
bool isCovered(vector<vector<int>>& ranges, int left, int right) {
sort(ranges.begin(),ranges.end());//第一列元素进行排序
int cnt = left;
for (int i = 0; i < ranges.size(); i++)
{
if (cnt >= ranges[i][0] && cnt <= ranges[i][1])//[left,ranges[i][1]]出现
cnt = ranges[i][1] + 1;//下一次改从ranges[i][1] + 1,ranges[i + 1][1]查找
if (cnt > right)//找到
return true;
}
return false;
}
};
法三:优化暴力法
bool isCovered(int** ranges, int rangesSize, int* rangesColSize, int left, int right){
int check[51];//51为[1,50]
memset(check, 0, sizeof(check));
for (int i = 0; i < rangesSize; i++)
{
int l = fmax(left,ranges[i][0]);
int r = fmin(right,ranges[i][1]);//[l,r] 与 [left,right]交集
for (int j = l; j <= r; j++)//
check[j] = 1;//只更新重合的部分
}
//重合的部分是否包含了[left,right]所有整数值
for (int i = left; i <= right; i++)
if (check[i] != 1) return false;
return true;
}
时间复杂度:时间复杂度 O(n) 与 O(n^2) 之间,故O(n方)
空间复杂度:O(n)
法四:差分数组
思路:
diff[i]覆盖整数i的的区间数量相对于覆盖 i - 1区间数量变化量。
在区间[l,r],l比l - 1多一个,r + 1比r少一个.起始下标+1,在终止下标之后-1
代码一:
参考老干妈是万能的
bool isCovered(int** ranges, int rangesSize, int* rangesColSize, int left, int right){
int diff[52];//按照差分数组存放中,起始下标+1,在终止下标之后-1
//起始下标0,终止下标51,共52个
memset(diff,0,sizeof(diff));
int idxSum[52];//前缀和
memset(idxSum,0,sizeof(idxSum));
for (int i = 0; i < rangesSize; i++)
{
++diff[ranges[i][0]];
--diff[ranges[i][1] + 1];//起始下标+1,在终止下标之后-1
}
for (int i = 1; i <= 51; i++)
idxSum[i] = idxSum[i - 1] + diff[i];
//从left到right判断是否满足sum > 0
for(int i = left; i <= right; i++)
{
if(idxSum[i] <= 0) return false;
}
return true;
}
代码二:空间优化
bool isCovered(int** ranges, int rangesSize, int* rangesColSize, int left, int right){
int diff[52];//按照差分数组存放中,起始下标+1,在终止下标之后-1
//起始下标0,终止下标51,共52个
memset(diff,0,sizeof(diff));
int idxSum = 0;//前缀和
for (int i = 0; i < rangesSize; i++)
{
++diff[ranges[i][0]];
--diff[ranges[i][1] + 1];//起始下标+1,在终止下标之后-1
}
for (int i = 1; i <= 50; i++)//题干条件给出1~50
{
idxSum += diff[i];
if (i >= left && i <= right && idxSum <= 0) return false;
}
return true;
}
以上是关于《LeetCode之每日一题》:100.检查是否区域内所有整数都被覆盖的主要内容,如果未能解决你的问题,请参考以下文章
《LeetCode之每日一题》:98.删除排序链表中的重复元素
《LeetCode之每日一题》:288.删除排序链表中的重复元素