|
| 1 | +// Time: O(n) |
| 2 | +// Space: O(n) |
| 3 | + |
| 4 | +class Solution { |
| 5 | +public: |
| 6 | + bool isRectangleCover(vector<vector<int>>& rectangles) { |
| 7 | + enum DIR {L = 0, B = 1, R = 2, T = 3}; |
| 8 | + int left = numeric_limits<int>::max(), bottom = numeric_limits<int>::max(), |
| 9 | + right = numeric_limits<int>::min(), top = numeric_limits<int>::min(); |
| 10 | + for (const auto& rect : rectangles) { |
| 11 | + left = min(left, rect[L]); |
| 12 | + bottom = min(bottom, rect[B]); |
| 13 | + right = max(right, rect[R]); |
| 14 | + top = max(top, rect[T]); |
| 15 | + } |
| 16 | + |
| 17 | + using P = pair<pair<int, int>, int>; |
| 18 | + enum CORNER {LB = 1, RB = 2, LT = 4, RT = 8}; |
| 19 | + unordered_map<int, unordered_map<int, int>> corner_count; |
| 20 | + vector<P> corners{{{L, B}, LB}, {{R, B}, RB}, {{L, T}, LT}, {{R, T}, RT}}; |
| 21 | + for (const auto& rect : rectangles) { |
| 22 | + for (const auto& corner : corners) { |
| 23 | + const auto x = rect[corner.first.first]; |
| 24 | + const auto y = rect[corner.first.second]; |
| 25 | + if (corner_count[x][y] & corner.second) { |
| 26 | + return false; |
| 27 | + } |
| 28 | + corner_count[x][y] |= corner.second; |
| 29 | + } |
| 30 | + } |
| 31 | + |
| 32 | + bool is_valid[16] = {false}; |
| 33 | + is_valid[LB | RB] = is_valid[LB | LT] = is_valid[RB | RT] = is_valid[LT | RT] = is_valid[LB | RB | LT | RT] = true; |
| 34 | + for (auto itx = corner_count.begin(); itx != corner_count.end(); ++itx) { |
| 35 | + const auto x = itx->first; |
| 36 | + for (auto ity = itx->second.begin(); ity != itx->second.end(); ++ity) { |
| 37 | + int y = ity->first; |
| 38 | + int mask = ity->second; |
| 39 | + if ((left < x && x < right) || (bottom < y && y < top)) { |
| 40 | + if (!is_valid[mask]) { |
| 41 | + return false; |
| 42 | + } |
| 43 | + } |
| 44 | + } |
| 45 | + } |
| 46 | + |
| 47 | + return true; |
| 48 | + } |
| 49 | +}; |
0 commit comments