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

每个矩形用左下角的点和右上角的点的坐标来表示。例如, 一个单位正方形可以表示为 [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:

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],
[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[], a[]) >= max(b[], b[]) || max(a[], a[]) <= min(b[], b[])
|| min(a[], a[]) >= max(b[], b[]) || max(a[], a[]) <= min(b[], b[]))
{
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 = ;
for (int i = ; i < rectangles.size();i++)
{
for (int r = ; r < i;r++)
{
if (Cover(rectangles[i], rectangles[r]))
{
return false;
}
}
minx = min(minx, min(rectangles[i][], rectangles[i][]));
miny = min(miny, min(rectangles[i][], rectangles[i][]));
maxx = max(maxx, max(rectangles[i][], rectangles[i][]));
maxy = max(maxy, max(rectangles[i][], rectangles[i][]));
sum += abs((rectangles[i][] - rectangles[i][])*(rectangles[i][] - rectangles[i][]));
}
return sum == (maxx - minx)*(maxy - miny);
}
};

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

第二遍:四叉树解法

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, , sizeof(Children));
}
~QuadNode()
{
for (int i = ; i < quad_count; i++)
{
if (Children[i])
{
delete Children[i];
Children[i] = NULL;
}
}
rectlist.clear();
}
QuadNode* GetDeepest(int index)
{
if (deep > )
{
//4个孩子都要创建
for (int r = ; r < QuadNode::quad_count; r++)
{
if (!Children[r])
{
int ix = r == QuadNode::quad_1 || r == QuadNode::quad_3 ? minx : (minx + maxx) / ;
int ax = r == QuadNode::quad_1 || r == QuadNode::quad_3 ? (minx + maxx) / : maxx; int iy = r == QuadNode::quad_1 || r == QuadNode::quad_2 ? miny : (miny + maxy) / ;
int ay = r == QuadNode::quad_1 || r == QuadNode::quad_2 ? (miny + maxy) / : maxy;
QuadNode *node = new QuadNode(data, ix, ax, iy, ay, deep - , 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][] >= minx && (*data)[index][] <= maxx && (*data)[index][] >= miny && (*data)[index][] <= 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 = ; i < quad_count && Children[i]; i++)
{
int vec[] = { minx, miny, maxx, maxy };
vector<int> para(vec, vec + );
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[], a[]) >= max(b[], b[]) || max(a[], a[]) <= min(b[], b[])
|| min(a[], a[]) >= max(b[], b[]) || max(a[], a[]) <= min(b[], b[]))
{
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 - )) == )
{
double L = log(max*1.0) / log(2.0);
lg = (int)L + ;
return max;
}
else
{
double L = log(max*1.0) / log(2.0);
lg = (int)L + ;
return (int)pow( * 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 = ;
for (int i = ; i < rectangles.size(); i++)
{
minx = min(minx, min(rectangles[i][], rectangles[i][]));
miny = min(miny, min(rectangles[i][], rectangles[i][]));
maxx = max(maxx, max(rectangles[i][], rectangles[i][]));
maxy = max(maxy, max(rectangles[i][], rectangles[i][]));
}
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, ); for (int i = ; i < rectangles.size();i++)
{
if (root->CheckCover(i))
{
return false;
}
sum += abs((rectangles[i][] - rectangles[i][])*(rectangles[i][] - rectangles[i][]));
}
delete root;
return sum == (maxx - minx)*(maxy - miny);
}
};

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

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

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

   long long int getHash(int x, int y)
{
long long int t = << ;
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 = ;
unordered_set<long long int> st;
for (int i = ; i < rectangles.size(); i++)
{
minx = min(minx, min(rectangles[i][], rectangles[i][]));
miny = min(miny, min(rectangles[i][], rectangles[i][]));
maxx = max(maxx, max(rectangles[i][], rectangles[i][]));
maxy = max(maxy, max(rectangles[i][], rectangles[i][]));
sum += abs((rectangles[i][] - rectangles[i][])*(rectangles[i][] - rectangles[i][]));
long long int lu = getHash(rectangles[i][], rectangles[i][]);
long long int ld = getHash(rectangles[i][], rectangles[i][]);
long long int ru = getHash(rectangles[i][], rectangles[i][]);
long long int rd = getHash(rectangles[i][], rectangles[i][]);
if (st.count(lu) == ) st.insert(lu);
else st.erase(lu);
if (st.count(ld) == ) st.insert(ld);
else st.erase(ld);
if (st.count(ru) == ) st.insert(ru);
else st.erase(ru);
if (st.count(rd) == ) st.insert(rd);
else st.erase(rd);
} return sum == (maxx - minx)*(maxy - miny) && st.size() ==
&& st.count(getHash(minx, miny)) ==
&& st.count(getHash(minx, maxy)) ==
&& st.count(getHash(maxx, miny)) ==
&& st.count(getHash(maxx, maxy)) == ;
}

吐血!

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. vue解决跨域问题

    vue解决跨域问题 vue跨域解决方法和小总结 vue项目中,前端与后台进行数据请求或者提交的时候,如果后台没有设置跨域,前端本地调试代码的时候就会报“No 'Access-Control-Allow ...

  2. mysql5.7官网直译SQL语句优化--select语句优化

    8.2 sql语句优化 大致内容如下: 8.2.1:SELECT语句的优化 8.2.2:优化子查询,派生表和试图引用 8.2.3:优化INFORMATION_SCHEMA查询 8.2.4:优化数据改变 ...

  3. 洛谷 P3507 [POI2010]GRA-The Minima Game

    P3507 [POI2010]GRA-The Minima Game 题目描述 Alice and Bob learned the minima game, which they like very ...

  4. ORACLE-014:oracle中查看DBLinkpassword

    dblink在数据库中使用是比較多的,简单方便.只是随着oracle安全机制的加强.普通用户登录仅仅能看到,username以及连接字符串.那么dblinkpassword怎样查看呢? 非常easy. ...

  5. Linux以下的两种文件锁

    文件锁是一种文件读写机制.在不论什么特定的时间仅仅同意一个进程訪问一个文件. 利用这样的机制可以使读写单个文件的过程变得更安全. 在这篇文章中.我们将探讨Linux中不同类型的文件锁,并通过演示样例程 ...

  6. iOS:简单使用UIAlertVIew和UIActionSheet

    做iOS开发的同学想必都用过UIAlertVIew或者UIActionSheet.UIAlertVIew 可以弹出一个出现在屏幕中间的提示视图,给用户展示信息,并让用户自己选择操作,UIActionS ...

  7. Java多线程编程模式实战指南(一):Active Object模式--转载

    本文由黄文海首次发布在infoq中文站上:http://www.infoq.com/cn/articles/Java-multithreaded-programming-mode-active-obj ...

  8. direct2d: antialiasing and drawing a line with a 1 pixel stroke

    http://xboxforums.create.msdn.com/forums/t/61448.aspx I'm currently porting a number of custom MFC C ...

  9. (GDOI2018模拟九)【UOJ#192】【UR#14】最强跳蚤

    (开头先Orz myh) 原题目: 在人类和跳蚤的战争初期,人们凭借着地理优势占据了上风——即使是最强壮的跳蚤,也无法一下越过那一堵坚固的城墙. 在经历了惨痛的牺牲后,跳蚤国王意识到再这样下去,跳蚤国 ...

  10. linux下mysqldump简单命令导出数据库和表

    进入mysql的bin目录执行: 导出单个表: mysqldump -uroot -ppassword --database dbname --tables users > /home/root ...