LeetCode 391:完美矩形
题目
给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) ,右上顶点是 (ai, bi) 。
如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否则,返回 false
解题思路
精准覆盖的所代表的意义:
(1)矩形区域中不能有空缺,即矩形区域的面积等于所有矩形的面积之和;
(2)矩形区域中不能有相交区域。
那么难点在于怎么判断没有相交区域,如果分块面积和等于总面积,且小块的角上的点都是成对出现的,则必然不会出现相交区域。
实现
class Solution {
public:
bool isRectangleCover(vector<vector<int>>& rectangles) {
map<pair<int, int>, int> num;
int minx = rectangles[0][0], miny = rectangles[0][1], maxx = rectangles[0][2], maxy = rectangles[0][3];
int resSum = 0;
for (int i = 0; i < rectangles.size(); i++) {
resSum += (rectangles[i][2] - rectangles[i][0]) * (rectangles[i][3] - rectangles[i][1]);
minx = min(minx, rectangles[i][0]);
miny = min(miny, rectangles[i][1]);
maxx = max(maxx, rectangles[i][2]);
maxy = max(maxy, rectangles[i][3]);
num[make_pair(rectangles[i][0], rectangles[i][1])]++;
num[make_pair(rectangles[i][0], rectangles[i][3])]++;
num[make_pair(rectangles[i][2], rectangles[i][1])]++;
num[make_pair(rectangles[i][2], rectangles[i][3])]++;
}
if (resSum != (maxx - minx) * (maxy - miny))
return false;
num[make_pair(minx, miny)]--;
num[make_pair(minx, maxy)]--;
num[make_pair(maxx, maxy)]--;
num[make_pair(maxx, miny)]--;
for (auto & it : num) {
if (it.second != 2 && it.second != 4 && it.second != 0)
return false;
}
return true;
}
};
最后附上一个兄弟的牛逼简洁答案,使用二维差分的方式实现:
class Solution {
public:
bool isRectangleCover(vector<vector<int>>& rectangles) {
map<pair<int, int>, int> mp;
for (auto &item : rectangles) {
int x = item[0], y = item[1], a = item[2], b = item[3];
if (++mp[{x, y}] == 0) mp.erase({x, y});
if (--mp[{x, b}] == 0) mp.erase({x, b});
if (++mp[{a, b}] == 0) mp.erase({a, b});
if (--mp[{a, y}] == 0) mp.erase({a, y});
}
return mp.size() == 4 && mp.begin()->second == 1;
}
};