leetCode 检查是否区域内所有整数都被覆盖

给你一个二维整数数组 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

方法一(暴力循环)、
在用新的数组记录值是否包含,包含的flag记录为true,代表该点已经被包含。
当我们查询时,如果查询left与right之间只要有一点为false,返回flase

publicboolean isCovered(int[][] ranges, int left, int right) {
    boolean[] flag = new boolean[];
    for(int[] range : ranges){
        for(int i = range[0]; i <= range[1];i++){
            //已经记录过就不做处理(没有记录该值重复多少次)
            if(!flag[i]){
                flag[i] = true;
            }
        }
    }
    //从left到right判断是否满足flag都为true
    for (int i = left; i <= right; i++) {
        if(!flag[i]){
            return false;
        }
    }
    return true;
}

方法二(排序)、

如将区间的起始点从小到大排序,然后每次比较,如果拿到的区间[l,r],left在区间内,即 l <= left <= r,
那么可知,[left,r]便已经被覆盖,接下来只需接续检查剩余空白部分,让left = r + 1, 如果最后left可以超过right,则区间全部被覆盖。为true。

public boolean isCovered(int[][] ranges, int left, int right) {
    //根据数组中的第一个节点进行排序
    Arrays.sort(ranges, Comparator.comparingInt(range -> range[0]));
    for(int[] range : ranges) {
        //如果left在当前区间,那么left到range[1]的区间就已经被覆盖,下一个区间只需要判断range[1]+1到right是否被覆盖
        if(range[0] <= left && range[1] >=left){
            left = range[1]+1;
        }
    }
    //left可以超过right,则区间全部被覆盖
    return left > right;
}

方法三(差分数组)、
差分数组diff表示相邻格之间,是否被覆盖的变化量。
1、diff[i]++,代表在i位置上有新的覆盖
2、若覆盖到j结束了呢?此时j依然是覆盖,但是j+1不在覆盖状态,所以在j+1处 -1;即diff[j+1]–;
3、差分数组求前缀和;
4、从left到right判断是否满足sum > 0

private static boolean isCovered3(int[][] ranges, int left, int right) {
    int[] diff = new int[52];
    //对差分数组进行处理
    for (int[] range : ranges) {
        diff[range[0]]++;
        diff[range[1] + 1]--;
    }

    //根据差分数组处理前缀和(长度可以值定义当right+1的位置,不需要定义52个)
    int[] sum = new int[right+1];
    for (int i = 1; i < right+1; i++) {
        sum[i] = diff[i] + sum[i-1];
    }

    //从left到right判断是否满足sum > 0
    for(int i = left; i <= right; i++){
        if(sum[i] <= 0) {
            return false;
        }
    }
    return true;
}

转载于:https://www.ycblog.top/article?articleId=143&pageNum=1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值