咱們有 N 個與座標軸對齊的矩形, 其中 N > 0, 判斷它們是否能精確地覆蓋一個矩形區域。node
每一個矩形用左下角的點和右上角的點的座標來表示。例如, 一個單位正方形能夠表示爲 [1,1,2,2]。 ( 左下角的點的座標爲 (1, 1) 以及右上角的點的座標爲 (2, 2) )。數組
示例 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:this
rectangles = [ [1,1,2,3], [1,3,2,4], [3,1,4,2], [3,2,4,4] ] 返回 false。兩個矩形之間有間隔,沒法覆蓋成一個矩形。
示例 3:spa
rectangles = [ [1,1,3,3], [3,1,4,2], [1,3,2,4], [3,2,4,4] ] 返回 false。圖形頂端留有間隔,沒法覆蓋成一個矩形。
示例 4:指針
rectangles = [ [1,1,3,3], [3,1,4,2], [1,3,2,4], [2,2,4,4] ] 返回 false。由於中間有相交區域,雖然造成了矩形,但不是精確覆蓋。
這道題我在寫前兩個解法的時候還沒ac經過,可是已經忍不住要寫了。思路仍是很清晰的,遍歷矩形,算有沒有重合,面積累加,最後看看總面積是否是最大範圍的覆蓋的矩形的面積。
第一遍暴力解法:
class Solution { public: bool Cover(vector<int>& a, vector<int>&b) { if (min(a[0], a[2]) >= max(b[0], b[2]) || max(a[0], a[2]) <= min(b[0], b[2]) || min(a[1], a[3]) >= max(b[1], b[3]) || max(a[1], a[3]) <= min(b[1], b[3])) { return false; } return true; } bool isRectangleCover(vector<vector<int>>& rectangles) { int minx, miny, maxx, maxy; minx = miny = INT_MAX; maxx = maxy = INT_MIN; long long int sum = 0; for (int i = 0; i < rectangles.size();i++) { for (int r = 0; r < i;r++) { if (Cover(rectangles[i], rectangles[r])) { return false; } } minx = min(minx, min(rectangles[i][0], rectangles[i][2])); miny = min(miny, min(rectangles[i][1], rectangles[i][3])); maxx = max(maxx, max(rectangles[i][0], rectangles[i][2])); maxy = max(maxy, max(rectangles[i][1], rectangles[i][3])); sum += abs((rectangles[i][0] - rectangles[i][2])*(rectangles[i][1] - rectangles[i][3])); } return sum == (maxx - minx)*(maxy - miny); } };
果不其然掛了,測試最後兩組都是3w+的數據量code
第二遍:四叉樹解法blog
class QuadNode { public: enum{ quad_1,//四個象限 quad_2, quad_3, quad_4, quad_count, }; vector<vector<int>>* data; QuadNode* Children[quad_count];//孩子指針,數組大小爲8 QuadNode* Parent;//父節點指針 typedef std::list<int> RecList; typedef std::list<int>::iterator RecListIter; RecList rectlist;//攜帶的參數 實體列表 int quad;//在父節點中的象限 int deep;//本身所在的層索引 int minx,miny; int maxx,maxy; QuadNode(vector<vector<int>>* data, int x1, int x2, int y1, int y2, int dp, int qd) { minx = x1; maxx = x2; miny = y1; maxy = y2; deep = dp; quad = qd; Parent = NULL; this->data = data; memset(Children, 0, sizeof(Children)); } ~QuadNode() { for (int i = 0; i < quad_count; i++) { if (Children[i]) { delete Children[i]; Children[i] = NULL; } } rectlist.clear(); } QuadNode* GetDeepest(int index) { if (deep > 0) { //4個孩子都要建立 for (int r = 0; r < QuadNode::quad_count; r++) { if (!Children[r]) { int ix = r == QuadNode::quad_1 || r == QuadNode::quad_3 ? minx : (minx + maxx) / 2; int ax = r == QuadNode::quad_1 || r == QuadNode::quad_3 ? (minx + maxx) / 2 : maxx; int iy = r == QuadNode::quad_1 || r == QuadNode::quad_2 ? miny : (miny + maxy) / 2; int ay = r == QuadNode::quad_1 || r == QuadNode::quad_2 ? (miny + maxy) / 2 : maxy; QuadNode *node = new QuadNode(data, ix, ax, iy, ay, deep - 1, r); node->Parent = this; Children[r] = node; } if (Children[r]->CheckInRange(index)) { return Children[r]->GetDeepest(index); } } } return this; } bool CheckInRange(int index) { if ((*data)[index][0] >= minx && (*data)[index][2] <= maxx && (*data)[index][1] >= miny && (*data)[index][3] <= maxy) { return true; } return false; } bool CheckCover(int index) { QuadNode* n = GetDeepest(index); QuadNode* parent = n->Parent; while (parent) { if (parent->CheckWithTrianglelist(index)) { return true; } parent = parent->Parent; } if (n->CollisionCheck(index)) return true; n->rectlist.push_back(index); return false; } bool CollisionCheck(int index) { return CheckWithTrianglelist(index) || CheckWithSubSpace(index); } bool CheckWithTrianglelist(int index) { RecListIter itr = rectlist.begin(); while (itr != rectlist.end()) { int id = *itr; if (Cover((*data)[id], (*data)[index])) { return true; } itr++; } return false; } bool CheckWithSubSpace(int index) { bool collision = false; for (int i = 0; i < quad_count && Children[i]; i++) { int vec[] = { minx, miny, maxx, maxy }; vector<int> para(vec, vec + 4); if (Cover((*data)[index], para)) { collision |= Children[i]->CollisionCheck(index); } if (collision) { return true; } } return false; } bool Cover(vector<int>& a, vector<int>&b) { if (min(a[0], a[2]) >= max(b[0], b[2]) || max(a[0], a[2]) <= min(b[0], b[2]) || min(a[1], a[3]) >= max(b[1], b[3]) || max(a[1], a[3]) <= min(b[1], b[3])) { return false; } return true; } }; class Solution { public: int GetMax2Power(int xmax, int ymax, int& lg) { int max = xmax; if (ymax > max) max = ymax; if ((max & (max - 1)) == 0) { double L = log(max*1.0) / log(2.0); lg = (int)L + 1; return max; } else { double L = log(max*1.0) / log(2.0); lg = (int)L + 2; return (int)pow(2 * 1.0, lg - 1.0); } } bool isRectangleCover(vector<vector<int>>& rectangles) { int minx, miny, maxx, maxy; minx = miny = INT_MAX; maxx = maxy = INT_MIN; long long int sum = 0; for (int i = 0; i < rectangles.size(); i++) { minx = min(minx, min(rectangles[i][0], rectangles[i][2])); miny = min(miny, min(rectangles[i][1], rectangles[i][3])); maxx = max(maxx, max(rectangles[i][0], rectangles[i][2])); maxy = max(maxy, max(rectangles[i][1], rectangles[i][3])); } int mx = max(abs(maxx), abs(minx)); int my = max(abs(maxy), abs(miny)); int range, lg; range = GetMax2Power(mx, my, lg); //四叉樹 QuadNode* root = new QuadNode(&rectangles, -range, range, -range, range, lg, 0); for (int i = 0; i < rectangles.size();i++) { if (root->CheckCover(i)) { return false; } sum += abs((rectangles[i][0] - rectangles[i][2])*(rectangles[i][1] - rectangles[i][3])); } delete root; return sum == (maxx - minx)*(maxy - miny); } };
覺得沒什麼問題了,跑一下又超時了,真是噁心的一p啊。拿測試數據跑一跑發現,幾乎95%的數據都在邊界上,四叉樹沒法往下細化。寫個四叉樹容易嗎???索引
只能硬着頭皮繼續想了,果真沒有想到。參考了下別人的歪門邪道,感受前面寫的東西都白瞎了。有時候解決問題,還得靠技巧。get
解法三:全部的矩形頂點,有且只有四個邊角是隻出現一次,剩下的頂點要麼兩次,要麼四次
long long int getHash(int x, int y) { long long int t = 2 << 16; return x*t + y; } bool isRectangleCover(vector<vector<int>>& rectangles) { int minx, miny, maxx, maxy; minx = miny = INT_MAX; maxx = maxy = INT_MIN; long long int sum = 0; unordered_set<long long int> st; for (int i = 0; i < rectangles.size(); i++) { minx = min(minx, min(rectangles[i][0], rectangles[i][2])); miny = min(miny, min(rectangles[i][1], rectangles[i][3])); maxx = max(maxx, max(rectangles[i][0], rectangles[i][2])); maxy = max(maxy, max(rectangles[i][1], rectangles[i][3])); sum += abs((rectangles[i][0] - rectangles[i][2])*(rectangles[i][1] - rectangles[i][3])); long long int lu = getHash(rectangles[i][0], rectangles[i][3]); long long int ld = getHash(rectangles[i][0], rectangles[i][1]); long long int ru = getHash(rectangles[i][2], rectangles[i][3]); long long int rd = getHash(rectangles[i][2], rectangles[i][1]); if (st.count(lu) == 0) st.insert(lu); else st.erase(lu); if (st.count(ld) == 0) st.insert(ld); else st.erase(ld); if (st.count(ru) == 0) st.insert(ru); else st.erase(ru); if (st.count(rd) == 0) st.insert(rd); else st.erase(rd); } return sum == (maxx - minx)*(maxy - miny) && st.size() == 4 && st.count(getHash(minx, miny)) == 1 && st.count(getHash(minx, maxy)) == 1 && st.count(getHash(maxx, miny)) == 1 && st.count(getHash(maxx, maxy)) == 1; }
吐血!