力扣 1893. 检查是否区域内所有整数都被覆盖

题目来源:https://leetcode-cn.com/problems/check-if-all-the-integers-in-a-range-are-covered/

大致题意:
给定一个二维数组,其中每个以为一维数组为一个闭区间。再给定一个left和right,判断left到right之间的所有数是否在之前给定的区间中(区间可能有重叠)

思路

暴力

遍历每个区间,然后给区间内所有数做标记。
之后从left遍历到right,查看是否所有数都被标记。

排序
  1. 先对区间按照左边界升序排序
  2. 遍历所有区间,若left在当前区间中,left更改为当前区间右边界+1
  3. 若left大于right,则说明所有数都在曲建忠,返回true;反之,返回false

代码:

public boolean isCovered(int[][] ranges, int left, int right) {
		boolean ans = true
        // 排序
        Arrays.sort(ranges, (a1, a2) -> a1[0] > a2[0]);
        for (int[] range : ranges) {
            if (range[0]<= left && left <= range[1]) // 判断left是否在当前区间
                left = range[1] + 1;
        }
        ans = left > right;
        return ans;
}
差分

使用差分对区间数进行标记。

  • 已知所有区间在[1, 50]内,所以创建一个适当大小(52,考虑到索引0和索引51)的diff数组。
  • 遍历所有区间,区间左边界对应的diff加1,右边界+1的位置对应的diff-1
  • 为什么这样做?
  • 因为这样,可以在从前往后遍历时,使用一个score来记录遍历位置的diff和,那么所有在给定区间的数(数即为对应的diff索引)的score应当是大于0的。那么也就是,不在区间的数,其score不超过0。
  • 为什么在区间的数,其score大于0?
  • 因为,若当前数num,在区间[x, y]中,那么在遍历到x的时候,score已经+1,而直到y score的值都不会减,定然是大于0。若中间穿插其他区间,那么穿插区间要么都在num左边(这样score已经+1又-1,score不受影响),要么穿插区间覆盖num(这样score在穿插区间左边界+1,还未到右边界,不用-1,score更大,不影响结果),要么穿插区间在num右边(这样score的改变当然和当前位置无关)

因为给定区间在[1, 50],所以接下来再遍历该区间。若当前遍历的数在所求区间(left至right)中,且其差分分值小于0,那么其不在之前的所有区间中,直接返回false。

public boolean isCovered(int[][] ranges, int left, int right) {
        
        boolean ans = true;
        int[] diff = new int[52];
        for (int[] range : ranges) { // 差分标记
            diff[range[0]]++;
            diff[range[1]+1]--;
        }
        int score = 0;
        for (int i = 1; i <= 50; i++) {
            score += diff[i]; // 当前数的差分分值
            if (left <= i && i <= right && score <= 0) {
            // 若当前数在所求区间中,且差分分值小于0
                ans = false;
                break;
            }
        }
        return ans;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三更鬼

谢谢老板!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值