第850题 矩形面积 II(扫描线)

题目描述:

我们给出了一个(轴对齐的)二维矩形列表 rectangles 。对于 rectangle[i] = [x1, y1, x2, y2],其中(x1,y1)是矩形 i 左下角的坐标, (xi1, yi1) 是该矩形 左下角 的坐标, (xi2, yi2) 是该矩形 右上角 的坐标。

计算平面中所有 rectangles 所覆盖的 总面积 。任何被两个或多个矩形覆盖的区域应只计算 一次 。

返回 总面积 。因为答案可能太大,返回 109 + 7 的 模 。

LevelAC rate
Hard58.2%


题目解析:

题目描述的意思非常简单,就是需要计算出,多个矩阵覆盖区域的面积,重叠部分不算,我一开始想的是使用一个二维矩阵,记录不同x坐标下区域的高度,但是对于后续的处理就没有想出来了,看了答案,答案的代码好多,然后采用了最简洁的一个答案版本,并根据意思自己写了出来。

先简单介绍一下原理,将矩阵的x坐标存储下来,不管是入边的x还是出边的x,然后按从小到大对x的值进行排序,找到扫描线划分的位置,然后使用一个遍历所给的矩形区域,如果区域将我两条相邻扫描线都覆盖上了,表明该矩形覆盖了我两条扫描线中的区域,将所有满足条件的矩形的下端和上端通过一个链表记录下来,通过并集来对整体长度进行计算,这个时候,整体的长度乘上两条扫描线的宽度就是所有矩形区域在这两条扫描线中覆盖区域的大小,代码如下:


class Solution {
    
    int MOD = (int)1e9+7;

    public int rectangleArea(int[][] rectangles) {
        long ans = 0;
        List<Integer> list = new ArrayList<Integer>();
        for(int[] med:rectangles){
            list.add(med[0]);
            list.add(med[2]);
        }
        Collections.sort(list);
        for(int i = 1 ; i<list.size() ; i++){
            int a = list.get(i-1);
            int b = list.get(i);
            int len = b-a;
            if(len==0)continue;
            List<int[]> A_set = new ArrayList<>();
            for(int[] med:rectangles){
                if(med[0]<=a&&med[2]>=b)A_set.add(new int[]{med[1],med[3]});
            }
            Collections.sort(A_set,(l1,l2)->{
                return l1[0]!=l2[0]?l1[0]-l2[0]:l1[1]-l2[1];
            });
            long tol = 0 ; int l = -1 ; int r = -1;
            for(int[] med : A_set){
                if(med[0]>r){
                    tol += r-l;
                    r = med[1];
                    l = med[0];
                }
                else{
                    r = Math.max(r,med[1]);
                }
            }
            tol += r-l;
            ans += tol*len;
        }
        return (int)(ans%MOD);
    }
}

执行用时:10 ms, 在所有 Java 提交中击败了23.03%的用户

内存消耗:41.3 MB, 在所有 Java 提交中击败了40.79%的用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值