391. 完美矩形

253 阅读1分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战」。

题目

给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) ,右上顶点是 (ai, bi) 。

如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否则,返回 false 。

截屏2021-11-16 下午10.44.42.png

思路分析

最开始的思路是通过确认大矩形的两个顶点,计算出(如果存在)大矩形的面积,并计算所有小矩形的面积和,通过面积的比较,来判断是否存在重叠或空白范围(因为如果面积不相同,则必然发生了空白或重叠的现象)

代码如下

bool isRectangleCover(vector<vector<int>>& rectangles) {
        int mian = 0;
        int minx = 100005, miny = 100005, maxx = -100005, maxy = -100005;
        for(int i = 0; i < rectangles.size(); i ++){
           mian += (rectangles[i][2] - rectangles[i][0]) * (rectangles[i][3] - rectangles[i][1]);
           if (rectangles[i][0] < minx) minx = rectangles[i][0];
           if (rectangles[i][1] < miny) miny = rectangles[i][1];
           if (rectangles[i][2] > maxx) maxx = rectangles[i][2];
           if (rectangles[i][3] > maxy) maxy = rectangles[i][3];
        }

        if ((maxy - miny) * (maxx - minx) != mian){
            return false;
        }
        return true;
    }

结果不尽人意

截屏2021-11-17 下午2.33.42.png

看了用例发现是重复了一个格子,空白了一个格子。

所以根据这个用例我们可以推断出这种大矩形小矩形的思路是走不通的,如果在初步过滤后,继续重复穷举判断是否有重叠空白的格子时间复杂度又过高,因此选择查看答案

答案给出了扫描线的方法,如图

截屏2021-11-17 下午2.49.52.png 完美矩形的所有小矩形的边必定成对出现,只有两个例外是大矩形顶点的竖边,因此我们可以通过枚举边代替枚举点,实现完美矩形的判断。