本文为LeetCode 391 完美矩形的题解。
391.
完美矩形 - 力扣(LeetCode) (leetcode-cn.com)链接
题目大意
给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi]
表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) ,右上顶点是
(ai, bi) 。
如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否则,返回
false 。
输入: rectangles =
[[1,1,3,3],[3,1,4,2],[3,2,4,4],[1,3,2,4],[2,3,3,4]]
输出: true 解释: 5
个矩形一起可以精确地覆盖一个矩形区域。
解题思路
感觉与其说是算法题,还不如说是找规律…
一开始我还想对输入的矩阵进行排序,利用线段树来进行操作,后面才发现是我想多了…
考虑矩形的四个顶点,当加入一个矩形的时候,用一个map来记录顶点,如果该顶点已经被加入过,那就消除该顶点在map中的记录,否则加入map进行标记。
如果所有矩形都精准覆盖了某个矩形区域,那么肯定只会剩下最大范围矩形区域的四个顶点,我们只需要判断最后map是否只剩下4个元素,并且这四个元素分别是最大矩形区域的四个顶点就行,另外我还添加了矩形面积的判断,加强约束。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class Solution { typedef pair<int, int> Point; #define min(a,b) (a<b? a:b) #define max(a,b) (a>b? a:b) public: bool isRectangleCover(vector<vector<int>>& rectangles) { map <Point, int> cnt; int minx, miny, maxx, maxy, cntS; minx = miny = (int)1e6; maxx = maxy = -(int)1e6; cntS = 0; for (const auto item : rectangles) { Point Point1(item[0], item[1]); Point Point2(item[2], item[1]); Point Point3(item[0], item[3]); Point Point4(item[2], item[3]); if (cnt.find(Point1) != cnt.end()) cnt.erase(Point1); else cnt[Point1] = 1; if (cnt.find(Point2) != cnt.end()) cnt.erase(Point2); else cnt[Point2] = 1; if (cnt.find(Point3) != cnt.end()) cnt.erase(Point3); else cnt[Point3] = 1; if (cnt.find(Point4) != cnt.end()) cnt.erase(Point4); else cnt[Point4] = 1;
minx = min(item[0], minx); minx = min(item[2], minx); maxx = max(item[0], maxx); maxx = max(item[2], maxx); miny = min(item[1], miny); miny = min(item[3], miny); maxy = max(item[1], maxy); maxy = max(item[3], maxy); cntS += (item[3] - item[1]) * (item[2] - item[0]); } return cnt.size() == 4 && ((maxx-minx) * (maxy-miny) == cntS) && cnt.count(Point(minx, miny)) && cnt.count(Point(minx, maxy)) && cnt.count(Point(maxx, miny)) && cnt.count(Point(maxx, maxy)); } };
|