391. Perfect Rectangle
问题描述:
Given N axis-aligned rectangles where N > 0, determine if they all together form an exact cover of a rectangular region.
Each rectangle is represented as a bottom-left point and a top-right point. For example, a unit square is represented as [1,1,2,2]. (coordinate of bottom-left point is (1, 1) and top-right point is (2, 2)).
Example 1:
rectangles = [ [1,1,3,3], [3,1,4,2], [3,2,4,4], [1,3,2,4], [2,3,3,4] ] Return true. All 5 rectangles together form an exact cover of a rectangular region.
Example 2:
rectangles = [ [1,1,2,3], [1,3,2,4], [3,1,4,2], [3,2,4,4] ] Return false. Because there is a gap between the two rectangular regions.
Example 3:
rectangles = [ [1,1,3,3], [3,1,4,2], [1,3,2,4], [3,2,4,4] ] Return false. Because there is a gap in the top center.
Example 4:
rectangles = [ [1,1,3,3], [3,1,4,2], [1,3,2,4], [2,2,4,4] ] Return false. Because two of the rectangles overlap with each other.
解题思路:
本题要求给出的矩形恰好组成一个矩形:不能有镂空,不能有重叠。要恰好组成矩形。
一开始有想是否跟 218.The Skyline Problem 相似,但是没有具体实现的头绪
看了MebiuW的解法后,利用了c++ STL自带的类型pair进行了实现
这个的解法的核心是:
1. 利用面积来保证不会重合
2.利用四个点来确定外边能够构成一个矩形
若所有矩形能够拼成一个完美的矩形,那么除了新矩形的四个顶点,其他的点只能出现偶数次,最多4次。
我用set来辅助我进行这个操作:set中含有就erase该元素,set中不含有就加入这个元素
这是一个充分条件但不是一个必要条件。
所以我们也需要检查:最后剩余的四个点是否就是四个顶点。
代码:
class Solution { public: bool isRectangleCover(vector<vector<int>>& rectangles) { if(rectangles.empty() || rectangles[0].empty()) return false; set<pair<int, int>> s; int area = 0; pair<int,int> b_l(INT_MAX, INT_MAX); pair<int,int> t_r(INT_MIN, INT_MIN); for(int i = 0; i < rectangles.size(); i++){ pair<int, int> cur_bl(rectangles[i][0], rectangles[i][1]); pair<int, int> cur_tr(rectangles[i][2], rectangles[i][3]); if(cur_bl < b_l){ b_l.first = cur_bl.first; b_l.second = cur_bl.second; } if(cur_tr > t_r){ t_r.first = cur_tr.first; t_r.second = cur_tr.second; } pair<int, int> cur_tl(rectangles[i][0],rectangles[i][3]); pair<int, int> cur_br(rectangles[i][2],rectangles[i][1]); if(s.count(cur_bl)){ s.erase(cur_bl); }else{ s.insert(cur_bl); } if(s.count(cur_tr)){ s.erase(cur_tr); }else{ s.insert(cur_tr); } if(s.count(cur_tl)){ s.erase(cur_tl); }else{ s.insert(cur_tl); } if(s.count(cur_br)){ s.erase(cur_br); }else{ s.insert(cur_br); } area += ((cur_tr.first - cur_bl.first)*(cur_tr.second - cur_bl.second)); } int total_area = (t_r.first - b_l.first)*(t_r.second - b_l.second); if(s.size() != 4 || area != total_area) return false; pair<int,int> b_r(t_r.first, b_l.second); pair<int,int> t_l(b_l.first, t_r.second); if(!s.count(b_r) || !s.count(b_l) || !s.count(t_r) || !s.count(t_l)) return false; return true; } };