题目
给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) ,右上顶点是 (ai, bi) 。
如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否则,返回 false 。
示例 1:
输入:rectangles = [[1,1,3,3],[3,1,4,2],[3,2,4,4],[1,3,2,4],[2,3,3,4]]
输出:true
解释:5 个矩形一起可以精确地覆盖一个矩形区域。
示例 2:
输入:rectangles = [[1,1,2,3],[1,3,2,4],[3,1,4,2],[3,2,4,4]]
输出:false
解释:两个矩形之间有间隔,无法覆盖成一个矩形。
示例 3:
输入:rectangles = [[1,1,3,3],[3,1,4,2],[1,3,2,4],[2,2,4,4]]
输出:false
解释:因为中间有相交区域,虽然形成了矩形,但不是精确覆盖。
参数范围:
1 <= rectangles.length <= 2 * 104
rectangles[i].length == 4
-105 <= xi, yi, ai, bi <= 105
2023年6月版
class Solution { public: bool isRectangleCover(vector<vector>& rectangles) { int iMaxX = 0, iMaxY = 0; { vector rectMax = rectangles[0]; long long llTotalArea = 0; for (auto& v : rectangles) { if (v[0] > v[2]) { swap(v[0], v[2]); } if (v[1] > v[3]) { swap(v[1], v[3]); } MinSelf(&rectMax[0], v[0]); MinSelf(&rectMax[1], v[1]); MaxSelf(&rectMax[2], v[2]); MaxSelf(&rectMax[3], v[3]); long long llWidth = v[2] - v[0]; llTotalArea += llWidth * (v[3] - v[1]); } //总面积必须和小矩形面积之和相等 if (llTotalArea != (long long)(rectMax[2] - rectMax[0])*(rectMax[3] - rectMax[1])) { return false; } for (auto& v : rectangles) { v[0] -= rectMax[0]; v[1] -= rectMax[1]; v[2] -= rectMax[0]; v[3] -= rectMax[1]; } iMaxX = rectMax[2] - rectMax[0]; iMaxY = rectMax[3] - rectMax[1]; } std::map<std::pair<int, int>, int> mPointNums; for (auto& v : rectangles) { mPointNums[{v[0], v[1]}]++; mPointNums[{v[0], v[3]}]++; mPointNums[{v[2], v[1]}]++; mPointNums[{v[2], v[3]}]++; } std::set<std::pair<int, int>> setRang; setRang.insert(make_pair(0, 0)); setRang.insert(make_pair(0, iMaxY)); setRang.insert(make_pair(iMaxX, 0)); setRang.insert(make_pair(iMaxX, iMaxY)); for (const auto& it : mPointNums) { if (setRang.count(it.first)) { if (1 != it.second) { return false; } continue; } if ((2 != it.second) && (4 != it.second)) { return false; } } return true; } };
2023年8月版
class Solution { public: bool isRectangleCover(vector<vector>& rectangles) { vector vRange = rectangles.front(); std::unordered_map<long long, vector> mMaskNum; for (const auto& v : rectangles) { vRange[0] = min(vRange[0],v[0]); vRange[1] = min(vRange[1], v[1]); vRange[2] = max(vRange[2], v[2]); vRange[3] = max(vRange[3], v[3]); mMaskNum[Mask(v[0], v[1])].emplace_back(0);//左下 mMaskNum[Mask(v[0], v[3])].emplace_back(1);//左上 mMaskNum[Mask(v[2], v[1])].emplace_back(1);//右下 mMaskNum[Mask(v[2], v[3])].emplace_back(3);//右上 } vector vMaskRange; vMaskRange.emplace_back(Mask(vRange[0], vRange[1])); vMaskRange.emplace_back(Mask(vRange[0], vRange[3])); vMaskRange.emplace_back(Mask(vRange[2], vRange[1])); vMaskRange.emplace_back(Mask(vRange[2], vRange[3])); for (const auto mask : vMaskRange) { if (1 != mMaskNum[mask].size()) { return false; } mMaskNum.erase(mask); } for ( auto& it : mMaskNum) { auto& v = it.second; if ((2 != it.second.size())&& (4 != it.second.size())) { return false; } std::sort(it.second.begin(), it.second.end()); bool bVilid = (0 == v[0]) && (3 == v.back()); if (2 == it.second.size()) { if (v[0] == v[1]) { return false; } bVilid = (v[0]/2 == v[1]/2) || (v[0]%2 == v[1]%2); } if (!bVilid) { return false; } } return true; } long long Mask(int x, int y) { x += 100 * 1000; y += 100 * 1000; return (long long)x * 1000 * 1000 + y; } };
扩展阅读
视频课程
有效学习:明确的目标 及时的反馈 拉伸区(难度合适),可以先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
相关下载
想高屋建瓴的学习算法,请下载《闻缺陷则喜算法册》doc版
https://download.csdn.net/download/he_zhidan/88348653
洒家想对大家说的话 |
闻缺陷则喜是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。 |
墨家名称的来源:有所得以墨记之。 |
如果程序是一条龙,那算法就是他的是睛 |
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17