我们有 N 个与坐标轴对齐的矩形, 其中 N > 0, 判断它们是否能精确地覆盖一个矩形区域。

每个矩形用左下角的点和右上角的点的坐标来表示。例如, 一个单位正方形可以表示为 [1,1,2,2]。 ( 左下角的点的坐标为 (1, 1) 以及右上角的点的坐标为 (2, 2) )。

示例 1:

  1. rectangles = [
  2. [1,1,3,3],
  3. [3,1,4,2],
  4. [3,2,4,4],
  5. [1,3,2,4],
  6. [2,3,3,4]
  7. ]
  8.  
  9. 返回 true5个矩形一起可以精确地覆盖一个矩形区域。
 

示例 2:

  1. rectangles = [
  2. [1,1,2,3],
  3. [1,3,2,4],
  4. [3,1,4,2],
  5. [3,2,4,4]
  6. ]
  7.  
  8. 返回 false。两个矩形之间有间隔,无法覆盖成一个矩形。
 

示例 3:

  1. rectangles = [
  2. [1,1,3,3],
  3. [3,1,4,2],
  4. [1,3,2,4],
  5. [3,2,4,4]
  6. ]
  7.  
  8. 返回 false。图形顶端留有间隔,无法覆盖成一个矩形。
 

示例 4:

  1. rectangles = [
  2. [1,1,3,3],
  3. [3,1,4,2],
  4. [1,3,2,4],
  5. [2,2,4,4]
  6. ]
  7.  
  8. 返回 false。因为中间有相交区域,虽然形成了矩形,但不是精确覆盖。
  9.  
  10. 这道题我在写前两个解法的时候还没ac通过,但是已经忍不住要写了。思路还是很清晰的,遍历矩形,算有没有重合,面积累加,最后看看总面积是不是最大范围的覆盖的矩形的面积。
    第一遍暴力解法:
  1. class Solution {
  2. public:
  3. bool Cover(vector<int>& a, vector<int>&b)
  4. {
  5. if (min(a[], a[]) >= max(b[], b[]) || max(a[], a[]) <= min(b[], b[])
  6. || min(a[], a[]) >= max(b[], b[]) || max(a[], a[]) <= min(b[], b[]))
  7. {
  8. return false;
  9. }
  10. return true;
  11. }
  12. bool isRectangleCover(vector<vector<int>>& rectangles) {
  13. int minx, miny, maxx, maxy;
  14. minx = miny = INT_MAX;
  15. maxx = maxy = INT_MIN;
  16. long long int sum = ;
  17. for (int i = ; i < rectangles.size();i++)
  18. {
  19. for (int r = ; r < i;r++)
  20. {
  21. if (Cover(rectangles[i], rectangles[r]))
  22. {
  23. return false;
  24. }
  25. }
  26. minx = min(minx, min(rectangles[i][], rectangles[i][]));
  27. miny = min(miny, min(rectangles[i][], rectangles[i][]));
  28. maxx = max(maxx, max(rectangles[i][], rectangles[i][]));
  29. maxy = max(maxy, max(rectangles[i][], rectangles[i][]));
  30. sum += abs((rectangles[i][] - rectangles[i][])*(rectangles[i][] - rectangles[i][]));
  31. }
  32. return sum == (maxx - minx)*(maxy - miny);
  33. }
  34. };

果不其然挂了,测试最后两组都是3w+的数据量

第二遍:四叉树解法

  1. class QuadNode
  2. {
  3. public:
  4. enum{
  5. quad_1,//四个象限
  6. quad_2,
  7. quad_3,
  8. quad_4,
  9. quad_count,
  10. };
  11. vector<vector<int>>* data;
  12. QuadNode* Children[quad_count];//孩子指针,数组大小为8
  13. QuadNode* Parent;//父节点指针
  14. typedef std::list<int> RecList;
  15. typedef std::list<int>::iterator RecListIter;
  16. RecList rectlist;//携带的参数 实体列表
  17. int quad;//在父节点中的象限
  18. int deep;//自己所在的层索引
  19. int minx,miny;
  20. int maxx,maxy;
  21. QuadNode(vector<vector<int>>* data, int x1, int x2, int y1, int y2, int dp, int qd)
  22. {
  23. minx = x1;
  24. maxx = x2;
  25. miny = y1;
  26. maxy = y2;
  27. deep = dp;
  28. quad = qd;
  29. Parent = NULL;
  30. this->data = data;
  31. memset(Children, , sizeof(Children));
  32. }
  33. ~QuadNode()
  34. {
  35. for (int i = ; i < quad_count; i++)
  36. {
  37. if (Children[i])
  38. {
  39. delete Children[i];
  40. Children[i] = NULL;
  41. }
  42. }
  43. rectlist.clear();
  44. }
  45. QuadNode* GetDeepest(int index)
  46. {
  47. if (deep > )
  48. {
  49. //4个孩子都要创建
  50. for (int r = ; r < QuadNode::quad_count; r++)
  51. {
  52. if (!Children[r])
  53. {
  54. int ix = r == QuadNode::quad_1 || r == QuadNode::quad_3 ? minx : (minx + maxx) / ;
  55. int ax = r == QuadNode::quad_1 || r == QuadNode::quad_3 ? (minx + maxx) / : maxx;
  56.  
  57. int iy = r == QuadNode::quad_1 || r == QuadNode::quad_2 ? miny : (miny + maxy) / ;
  58. int ay = r == QuadNode::quad_1 || r == QuadNode::quad_2 ? (miny + maxy) / : maxy;
  59. QuadNode *node = new QuadNode(data, ix, ax, iy, ay, deep - , r);
  60. node->Parent = this;
  61. Children[r] = node;
  62. }
  63. if (Children[r]->CheckInRange(index))
  64. {
  65. return Children[r]->GetDeepest(index);
  66. }
  67. }
  68. }
  69. return this;
  70. }
  71. bool CheckInRange(int index)
  72. {
  73. if ((*data)[index][] >= minx && (*data)[index][] <= maxx && (*data)[index][] >= miny && (*data)[index][] <= maxy)
  74. {
  75. return true;
  76. }
  77. return false;
  78. }
  79. bool CheckCover(int index)
  80. {
  81. QuadNode* n = GetDeepest(index);
  82. QuadNode* parent = n->Parent;
  83. while (parent)
  84. {
  85. if (parent->CheckWithTrianglelist(index))
  86. {
  87. return true;
  88. }
  89. parent = parent->Parent;
  90. }
  91.  
  92. if (n->CollisionCheck(index))
  93. return true;
  94. n->rectlist.push_back(index);
  95. return false;
  96. }
  97. bool CollisionCheck(int index)
  98. {
  99. return CheckWithTrianglelist(index) || CheckWithSubSpace(index);
  100. }
  101. bool CheckWithTrianglelist(int index)
  102. {
  103. RecListIter itr = rectlist.begin();
  104. while (itr != rectlist.end())
  105. {
  106. int id = *itr;
  107. if (Cover((*data)[id], (*data)[index]))
  108. {
  109. return true;
  110. }
  111. itr++;
  112. }
  113. return false;
  114. }
  115.  
  116. bool CheckWithSubSpace(int index)
  117. {
  118. bool collision = false;
  119. for (int i = ; i < quad_count && Children[i]; i++)
  120. {
  121. int vec[] = { minx, miny, maxx, maxy };
  122. vector<int> para(vec, vec + );
  123. if (Cover((*data)[index], para))
  124. {
  125. collision |= Children[i]->CollisionCheck(index);
  126. }
  127. if (collision)
  128. {
  129. return true;
  130. }
  131. }
  132. return false;
  133. }
  134.  
  135. bool Cover(vector<int>& a, vector<int>&b)
  136. {
  137. if (min(a[], a[]) >= max(b[], b[]) || max(a[], a[]) <= min(b[], b[])
  138. || min(a[], a[]) >= max(b[], b[]) || max(a[], a[]) <= min(b[], b[]))
  139. {
  140. return false;
  141. }
  142. return true;
  143. }
  144. };
  145. class Solution {
  146. public:
  147. int GetMax2Power(int xmax, int ymax, int& lg)
  148. {
  149. int max = xmax;
  150. if (ymax > max)
  151. max = ymax;
  152. if ((max & (max - )) == )
  153. {
  154. double L = log(max*1.0) / log(2.0);
  155. lg = (int)L + ;
  156. return max;
  157. }
  158. else
  159. {
  160. double L = log(max*1.0) / log(2.0);
  161. lg = (int)L + ;
  162. return (int)pow( * 1.0, lg - 1.0);
  163. }
  164. }
  165. bool isRectangleCover(vector<vector<int>>& rectangles) {
  166. int minx, miny, maxx, maxy;
  167. minx = miny = INT_MAX;
  168. maxx = maxy = INT_MIN;
  169. long long int sum = ;
  170. for (int i = ; i < rectangles.size(); i++)
  171. {
  172. minx = min(minx, min(rectangles[i][], rectangles[i][]));
  173. miny = min(miny, min(rectangles[i][], rectangles[i][]));
  174. maxx = max(maxx, max(rectangles[i][], rectangles[i][]));
  175. maxy = max(maxy, max(rectangles[i][], rectangles[i][]));
  176. }
  177. int mx = max(abs(maxx), abs(minx));
  178. int my = max(abs(maxy), abs(miny));
  179. int range, lg;
  180. range = GetMax2Power(mx, my, lg);
  181. //四叉树
  182. QuadNode* root = new QuadNode(&rectangles, -range, range, -range, range, lg, );
  183.  
  184. for (int i = ; i < rectangles.size();i++)
  185. {
  186. if (root->CheckCover(i))
  187. {
  188. return false;
  189. }
  190. sum += abs((rectangles[i][] - rectangles[i][])*(rectangles[i][] - rectangles[i][]));
  191. }
  192. delete root;
  193. return sum == (maxx - minx)*(maxy - miny);
  194. }
  195. };

以为没什么问题了,跑一下又超时了,真是恶心的一p啊。拿测试数据跑一跑发现,几乎95%的数据都在边界上,四叉树无法往下细化。写个四叉树容易吗???

只能硬着头皮继续想了,果然没有想到。参考了下别人的歪门邪道,感觉前面写的东西都白瞎了。有时候解决问题,还得靠技巧。

解法三:所有的矩形顶点,有且只有四个边角是只出现一次,剩下的顶点要么两次,要么四次

  1.    long long int getHash(int x, int y)
  2. {
  3. long long int t = << ;
  4. return x*t + y;
  5. }
  6. bool isRectangleCover(vector<vector<int>>& rectangles) {
  7. int minx, miny, maxx, maxy;
  8. minx = miny = INT_MAX;
  9. maxx = maxy = INT_MIN;
  10. long long int sum = ;
  11. unordered_set<long long int> st;
  12. for (int i = ; i < rectangles.size(); i++)
  13. {
  14. minx = min(minx, min(rectangles[i][], rectangles[i][]));
  15. miny = min(miny, min(rectangles[i][], rectangles[i][]));
  16. maxx = max(maxx, max(rectangles[i][], rectangles[i][]));
  17. maxy = max(maxy, max(rectangles[i][], rectangles[i][]));
  18. sum += abs((rectangles[i][] - rectangles[i][])*(rectangles[i][] - rectangles[i][]));
  19. long long int lu = getHash(rectangles[i][], rectangles[i][]);
  20. long long int ld = getHash(rectangles[i][], rectangles[i][]);
  21. long long int ru = getHash(rectangles[i][], rectangles[i][]);
  22. long long int rd = getHash(rectangles[i][], rectangles[i][]);
  23. if (st.count(lu) == ) st.insert(lu);
  24. else st.erase(lu);
  25. if (st.count(ld) == ) st.insert(ld);
  26. else st.erase(ld);
  27. if (st.count(ru) == ) st.insert(ru);
  28. else st.erase(ru);
  29. if (st.count(rd) == ) st.insert(rd);
  30. else st.erase(rd);
  31. }
  32.  
  33. return sum == (maxx - minx)*(maxy - miny) && st.size() ==
  34. && st.count(getHash(minx, miny)) ==
  35. && st.count(getHash(minx, maxy)) ==
  36. && st.count(getHash(maxx, miny)) ==
  37. && st.count(getHash(maxx, maxy)) == ;
  38. }

吐血!

Perfect Rectangle(完美矩形)的更多相关文章

  1. [LeetCode] Perfect Rectangle 完美矩形

    Given N axis-aligned rectangles where N > 0, determine if they all together form an exact cover o ...

  2. 391 Perfect Rectangle 完美矩形

    有 N 个与坐标轴对齐的矩形, 其中 N > 0, 判断它们是否能精确地覆盖一个矩形区域.每个矩形用左下角的点和右上角的点的坐标来表示.例如, 一个单位正方形可以表示为 [1,1,2,2]. ( ...

  3. Leetcode 391.完美矩形

    完美矩形 我们有 N 个与坐标轴对齐的矩形, 其中 N > 0, 判断它们是否能精确地覆盖一个矩形区域. 每个矩形用左下角的点和右上角的点的坐标来表示.例如, 一个单位正方形可以表示为 [1,1 ...

  4. Java实现 LeetCode 391 完美矩形

    391. 完美矩形 我们有 N 个与坐标轴对齐的矩形, 其中 N > 0, 判断它们是否能精确地覆盖一个矩形区域. 每个矩形用左下角的点和右上角的点的坐标来表示.例如, 一个单位正方形可以表示为 ...

  5. [Swift]LeetCode391. 完美矩形 | Perfect Rectangle

    Given N axis-aligned rectangles where N > 0, determine if they all together form an exact cover o ...

  6. [LeetCode] Rectangle Area 矩形面积

    Find the total area covered by two rectilinear rectangles in a2D plane. Each rectangle is defined by ...

  7. [LeetCode] Maximal Rectangle 最大矩形

    Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing all ones and ...

  8. Perfect Scrollbar – 完美的 jQuery 滚动条插件

    Perfect Scrollbar 是一个很小的,但完美的 jQuery 滚动插件.滚动条不会影响原来的设计布局,滚动条的设计是完全可定制的.你可以改变几乎所有的 CSS 样式的滚动条,滚动条设计对脚 ...

  9. Leetcode: Perfect Rectangle

    Given N axis-aligned rectangles where N > 0, determine if they all together form an exact cover o ...

随机推荐

  1. web.xml中Filter过滤器标签说明

    原文:http://www.cnblogs.com/edwardlauxh/archive/2010/03/11/1918618.html 在研究liferay框架中看到Web.xml中加入了过滤器的 ...

  2. [terry笔记]python FTP

    如下是作业,用python做一个ftp,主要利用socket. server端在linux下运行,在client端可以执行shell命令(静态的) 在client端输入get xxx,即可下载. 在c ...

  3. 洛谷 P1518 两只塔姆沃斯牛 The Tamworth Two

    P1518 两只塔姆沃斯牛 The Tamworth Two 题目背景 题目描述 两只牛逃跑到了森林里.农夫John开始用他的专家技术追捕这两头牛.你的任务是模拟他们的行为(牛和John). 追击在1 ...

  4. jQuery——map()函数以及它的java实现

    map()函数小简单介绍 map()函数一直都是我觉得比較有用的函数之中的一个,为什么这么说呢? 先来考虑一下.你是否碰到过下面场景:须要遍历一组对象取出每一个对象的某个属性(比方id)而且用分隔符隔 ...

  5. 【源代码】将一个整数的每位数分解并按逆序放入一个数组中(用递归算法)(C语言实现)

    帮朋友做的,好像是一个面试题.假设不过考察递归的话.应该是够了,程序的健壮性和通用性都非常一般的说-- #include <stdio.h> #include <stdlib.h&g ...

  6. linux 命令 xxd

    xxd,能够查看linux下文件的二进制表示.man一下xxd.能够得到下面信息 NAME        xxd - make a hexdump or do the reverse. SYNOPSI ...

  7. mysql的查询练习1

    1.多表查询

  8. HDU5411CRB and Puzzle(矩阵高速幂)

    题目链接:传送门 题意: 一个图有n个顶点.已知邻接矩阵.问点能够反复用长度小于m的路径有多少. 分析: 首先我们知道了邻接矩阵A.那么A^k代表的就是长度为k的路径有多少个. 那么结果就是A^0+A ...

  9. 继承QWidget的派生类控件不能设置QSS问题解决(使用style()->drawPrimitive(QStyle::PE_Widget,也就是画一个最简单最原始的QWidget,不要牵扯其它这么多东西)

    自定义控件时基类用了QWidget,发现qss设置不起作用,需要重载其paintEvent函数即可: 如下代码: void CCustomWidget::paintEvent(QPaintEvent* ...

  10. 当我们谈论Erlang Maps时,我们谈论什么 Part 2

    声明:本文讨论的Erlang Maps是基于17.0-rc2,时间2014-3-4.兴许Maps可能会出现语法或函数API上的有所调整,特此说明. 前情提要: [Erlang 0116] 当我们谈论E ...