391. 完美矩形
给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) ,右上顶点是 (ai, bi) 。
如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否则,返回 false 。
.
修改了大半天,在题解的帮助下完成,考虑到了顶点的情况,面积的情况,没有考虑到各个坐标的情况,加入了考虑各个坐标为奇数就False,为偶数就True的情况,同时,特意指出对于本人来说新的知识:
①自定义对象作为键值插入unorderd_map,需要重载两个部分。一个是"=="符号,以符合map创建时键值相同的特征。同时要重载hash()函数,存入的键值生成唯一的哈希值。
②函数()const,代表类或结构体中的变量无法被修改。
以下是自己写的代码(命名规则很混乱,希望未来自己能看懂):
1 #define _CRT_SECURE_NO_WARNINGS 2 #include <iostream> 3 #include <vector> 4 #include <string> 5 #include <algorithm> 6 #include <limits> 7 #include <unordered_map> 8 9 using namespace std; 10 11 class MyPosition 12 { 13 14 public: 15 MyPosition() {}; 16 MyPosition(int x, int y) :x(x), y(y) {}; 17 18 public: 19 bool operator == (const MyPosition& p) const{ 20 return x == p.x && y == p.y; 21 } 22 23 public: 24 int x; 25 int y; 26 }; 27 28 struct mapcompare 29 { 30 size_t operator()(const MyPosition& k) const{ 31 32 return hash<int>()(k.x) ^ hash<int>()(k.y); 33 } 34 }; 35 36 class Solution { 37 public: 38 bool isRectangleCover(vector<vector<int>>& rectangles) { 39 vector<vector<int>> rectanglesVer2; 40 41 unordered_map<MyPosition, int, mapcompare> mapAllPosition; 42 43 int minX = numeric_limits<int>::max(); 44 int minY = numeric_limits<int>::max(); 45 int maxX = numeric_limits<int>::min(); 46 int maxY = numeric_limits<int>::min(); 47 48 int totalArea = 0; 49 int totalAreaCheck = 0; 50 51 for (int i = 0; i < rectangles.size(); i++) 52 { 53 int tmp_minX = numeric_limits<int>::max(); //当前矩形的左下角X 54 int tmp_minY = numeric_limits<int>::max(); //当前矩形的左下角y 55 int tmp_maxX = numeric_limits<int>::min(); //当前矩形的右上角X 56 int tmp_maxY = numeric_limits<int>::min(); //当前矩形的右上角y 57 58 // 遍历X坐标(偶数列) 59 for (int j = 0; j < rectangles[0].size(); j += 2) { 60 minX = minX > rectangles[i][j] ? rectangles[i][j] : minX; 61 maxX = maxX > rectangles[i][j] ? maxX : rectangles[i][j]; 62 63 tmp_minX = tmp_minX > rectangles[i][j] ? rectangles[i][j] : tmp_minX; 64 tmp_maxX = tmp_maxX > rectangles[i][j] ? tmp_maxX : rectangles[i][j]; 65 } 66 67 // 遍历y坐标(奇数列) 68 for (int j = 1; j < rectangles[0].size(); j += 2) { 69 minY = minY > rectangles[i][j] ? rectangles[i][j] : minY; 70 maxY = maxY > rectangles[i][j] ? maxY : rectangles[i][j]; 71 72 tmp_minY = tmp_minY > rectangles[i][j] ? rectangles[i][j] : tmp_minY; 73 tmp_maxY = tmp_maxY > rectangles[i][j] ? tmp_maxY : rectangles[i][j]; 74 } 75 76 77 totalAreaCheck += (tmp_maxX - tmp_minX) * (tmp_maxY - tmp_minY); 78 79 80 int tmp_upRelativeMinX = tmp_minX; //当前矩形的左上角X 81 int tmp_upRelativeMaxY = tmp_maxY; //当前矩形的左上角y 82 int tmp_btRelativeMaxX = tmp_maxX; //当前矩形的右下角X 83 int tmp_btRelativeMinY = tmp_minY; //当前矩形的右下角y 84 85 rectanglesVer2.push_back({ tmp_upRelativeMinX , tmp_upRelativeMaxY , tmp_btRelativeMaxX , tmp_btRelativeMinY }); 86 } 87 88 totalArea = (maxX - minX) * (maxY - minY); //大矩形面积 89 90 if (totalAreaCheck != totalArea) { 91 return false; 92 } 93 94 int upRelativeMinX = minX; //大矩形的左上角X 95 int upRelativeMaxY = maxY; //大矩形的左上角y 96 int btRelativeMaxX = maxX; //大矩形的右下角X 97 int btRelativeMinY = minY; //大矩形的右下角y 98 99 int flag1 = 0; 100 int flag2 = 0; 101 int flag3 = 0; 102 int flag4 = 0; 103 104 for (int i = 0; i < rectangles.size(); i++) 105 { 106 int tmp_leftbutX = rectangles[i][0]; 107 int tmp_leftbutY = rectangles[i][1]; 108 int tmp_rightupX = rectangles[i][2]; 109 int tmp_rightupY = rectangles[i][3]; 110 111 if (minX == tmp_leftbutX && minY == tmp_leftbutY) { 112 flag1++; 113 } 114 115 if (maxX == tmp_rightupX && maxY == tmp_rightupY) { 116 flag2++; 117 } 118 119 // 录入字典 120 mapAllPosition[MyPosition(tmp_leftbutX, tmp_leftbutY)]++; 121 mapAllPosition[MyPosition(tmp_rightupX, tmp_rightupY)]++; 122 123 } 124 125 126 for (int i = 0; i < rectanglesVer2.size(); i++) 127 { 128 int tmp_leftupX = rectanglesVer2[i][0]; 129 int tmp_leftupY = rectanglesVer2[i][1]; 130 int tmp_rightbutX = rectanglesVer2[i][2]; 131 int tmp_rightbutY = rectanglesVer2[i][3]; 132 133 if (upRelativeMinX == tmp_leftupX && upRelativeMaxY == tmp_leftupY) { 134 flag3++; 135 } 136 137 if (btRelativeMaxX == tmp_rightbutX && btRelativeMinY == tmp_rightbutY) { 138 flag4++; 139 } 140 141 // 录入字典 142 mapAllPosition[MyPosition(tmp_leftupX, tmp_leftupY)]++; 143 mapAllPosition[MyPosition(tmp_rightbutX, tmp_rightbutY)]++; 144 } 145 146 147 if (flag1 != 1 || flag2 != 1 || flag3 != 1 || flag4 != 1) { 148 return false; 149 } 150 151 int numOcc = 0; 152 for (auto e : mapAllPosition) { 153 if (e.second == 1) { 154 numOcc++; 155 } 156 157 if (numOcc > 4) 158 return false; 159 160 if ((e.second % 2) == 1 && e.second != 1) 161 return false; 162 } 163 164 165 166 return true; 167 } 168 }; 169 170 int main(void) 171 { 172 //vector<vector<int>> rectangles = { {1,1},{0,1,3,2}, {1,0,2,2}}; 173 //vector<vector<int>> rectangles = { {1,1,3,3},{3,1,4,2},{3,2,4,4},{1,3,2,4},{2,3,3,4} }; 174 vector<vector<int>> rectangles = { {0,0,1,1},{0,0,2,1},{1,0,2,1}, {0,2,2,3} }; 175 Solution S; 176 177 cout << S.isRectangleCover(rectangles) << endl; 178 179 /*unordered_map<MyPosition, int, mapcompare> mapAllPosition; 180 181 MyPosition p1(10, 20); 182 183 for (int i = 0; i < 3; i++) 184 { 185 mapAllPosition[MyPosition(10, 20)]++; 186 187 } */ 188 189 190 getchar(); 191 return 0; 192 }
题解代码:
typedef pair<int, int> Point; class Solution { public: bool isRectangleCover(vector<vector<int>>& rectangles) { long area = 0; int minX = rectangles[0][0], minY = rectangles[0][1], maxX = rectangles[0][2], maxY = rectangles[0][3]; map<Point, int> cnt; for (auto & rect : rectangles) { int x = rect[0], y = rect[1], a = rect[2], b = rect[3]; area += (long) (a - x) * (b - y); minX = min(minX, x); minY = min(minY, y); maxX = max(maxX, a); maxY = max(maxY, b); Point point1({x, y}); Point point2({x, b}); Point point3({a, y}); Point point4({a, b}); cnt[point1] += 1; cnt[point2] += 1; cnt[point3] += 1; cnt[point4] += 1; } Point pointMinMin({minX, minY}); Point pointMinMax({minX, maxY}); Point pointMaxMin({maxX, minY}); Point pointMaxMax({maxX, maxY}); if (area != (long long) (maxX - minX) * (maxY - minY) || !cnt.count(pointMinMin) || !cnt.count(pointMinMax) || !cnt.count(pointMaxMin) || !cnt.count(pointMaxMax)) { return false; } cnt.erase(pointMinMin); cnt.erase(pointMinMax); cnt.erase(pointMaxMin); cnt.erase(pointMaxMax); for (auto & entry : cnt) { int value = entry.second; if (value != 2 && value != 4) { return false; } } return true; } };