【LeetCode】939. Minimum Area Rectangle 解题报告(Python & C++)
作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/
题目地址:https://leetcode.com/problems/minimum-area-rectangle/description/
题目描述
Given a set of points in the xy-plane, determine the minimum area of a rectangle formed from these points, with sides parallel to the x
and y
axes.
If there isn’t any rectangle, return 0.
Example 1:
Input: [[1,1],[1,3],[3,1],[3,3],[2,2]]
Output: 4
Example 2:
Input: [[1,1],[1,3],[3,1],[3,3],[4,1],[4,3]]
Output: 2
Note:
1 <= points.length <= 500
0 <= points[i][0] <= 40000
0 <= points[i][1] <= 40000
- All points are distinct.
题目大意
给了很多点,找出这些点中,任意选择4个点,形成一个长方形,要求长方形的边必须平行与坐标轴。求最小面积的长方形的面积是多少。
解题方法
确定对角线,找另外两点(4sum)
周赛的第三题,超时了很多次,确实需要优秀的解法才能通过。
最原始的想法就是,我们找出和坐标轴平行的三个点,来确定第四个点。这么做的话,时间复杂度是O(N^3),果然超时了。这说明我对4sum理解还不够深刻啊!两天前刚做过的454. 4Sum II,做法就是确定两个数字的和,然后看剩余的两个数字的和是否存在即可。也就是说4sum的时间复杂度只有O(N^2)。
这个题正确的做法是先确定对角线两个点!题目要求所有的边必须平行坐标轴,就是告诉我们只用确定对角线两个元素,剩余的两个点可以直接求出来即可!因此不需要确定3个点的O(N^3)的遍历。
所以啊,还是需要活学活用才行啊!
题目应该说清楚:面积为0的不算长方形。这样我们才能做两个对角线点不重合的判断。
时间复杂度是O(N^2),空间复杂度是O(N)。
Python代码如下:
class Solution(object):
def minAreaRect(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
points = map(tuple, points)
points.sort()
pset = set(points)
N = len(points)
res = float('inf')
for i in range(N - 1):
p1 = points[i]
for j in range(i + 1, N):
p4 = points[j]
if p4[0] == p1[0] or p4[1] == p1[1]:
continue
p2 = (p1[0], p4[1])
p3 = (p4[0], p1[1])
if p2 in pset and p3 in pset:
res = min(res, abs(p3[0] - p1[0]) * abs(p2[1] - p1[1]))
return res if res != float("inf") else 0
C++代码如下:
class Solution {
public:
int minAreaRect(vector<vector<int>>& points) {
set<pair<int, int>> pset;
const int N = points.size();
for (auto p : points) {
pset.insert(make_pair(p[0], p[1]));
}
int res = INT_MAX;
for (int i = 0; i < N; ++i) {
for (int j = i + 1; j < N; ++j) {
auto p1 = points[i];
auto p2 = points[j];
if (p1[0] == p2[0] || p1[1] == p2[1])
continue;
pair<int, int> p3 = {p1[0], p2[1]};
pair<int, int> p4 = {p2[0], p1[1]};
if (pset.count(p3) && pset.count(p4))
res = min(res, abs((p2[1] - p1[1]) * (p2[0] - p1[0])));
}
}
return res == INT_MAX ? 0 : res;
}
};
在上面的C++做法中使用的是pair做set的索引,由于题目给出的point的坐标是有范围的,所以可以使用40000 * p[0] + p[1]
作为确定一个点的方式。
class Solution {
public:
int minAreaRect(vector<vector<int>>& points) {
set<int> pset;
const int N = points.size();
for (auto p : points) {
pset.insert(40000 * p[0] + p[1]);
}
int res = INT_MAX;
for (int i = 0; i < N; ++i) {
for (int j = i + 1; j < N; ++j) {
auto p1 = points[i];
auto p2 = points[j];
if (p1[0] == p2[0] || p1[1] == p2[1])
continue;
vector<int> p3 = {p1[0], p2[1]};
vector<int> p4 = {p2[0], p1[1]};
if (pset.count(40000 * p3[0] + p3[1]) && pset.count(40000 * p4[0] + p4[1]))
res = min(res, abs((p2[1] - p1[1]) * (p2[0] - p1[0])));
}
}
return res == INT_MAX ? 0 : res;
}
};
字典保存出现的x值,y值的点
另一个高效的算法是使用字典进行保存。这样的话,如果我们确定了一个点(x,y),那么可以快速找到和它相同x坐标或者y坐标的所有点,然后只用遍历这些点就行了。
具体做法是,使用两个字典xdict和ydict,保存每个x,y对应的坐标。然后对相同的x进行O(N^2)的遍历。这时相当于确定了相同x的两个点,然后对相同的y再进行遍历,这样确定了第三个点。第四个点不用遍历,可以直接查找是不是在所有的点中出现了即可。
最坏时间复杂度是O(N^3),空间复杂度是O(N)。
class Solution(object):
def minAreaRect(self, points):
"""
:type points: List[List[int]]
:rtype: int
"""
points = map(tuple, points)
points.sort()
xdict, ydict = collections.defaultdict(list), collections.defaultdict(list)
pset = set()
res = float("inf")
for point in points:
xdict[point[0]].append(point)
ydict[point[1]].append(point)
pset.add(point)
for x1 in xdict.keys():
if len(xdict[x1]) == 1:
continue
for i in range(len(xdict[x1]) - 1):
p1 = xdict[x1][i]
for j in range(i + 1, len(xdict[x1])):
p2 = xdict[x1][j]
for p3 in ydict[p1[1]]:
if p3 != p1:
if (p3[0], p2[1]) in pset:
res = min(res, abs((p3[0] - p1[0]) * (p2[1] - p1[1])))
return res if res != float("inf") else 0
日期
2018 年 11 月 11 日 —— 剁手节快乐
【LeetCode】939. Minimum Area Rectangle 解题报告(Python & C++)的更多相关文章
- LeetCode 939. Minimum Area Rectangle (最小面积矩形)
题目标签:HashMap 题目给了我们一组 xy 上的点坐标,让我们找出 能组成矩形里最小面积的那个. 首先遍历所有的点,把x 坐标当作key 存入map, 把重复的y坐标 组成set,当作value ...
- 【leetcode】939. Minimum Area Rectangle
题目如下: Given a set of points in the xy-plane, determine the minimum area of a rectangle formed from t ...
- 【LeetCode】85. Maximal Rectangle 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/maximal- ...
- 【LeetCode】62. Unique Paths 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/unique-pa ...
- 【leetcode】963. Minimum Area Rectangle II
题目如下: Given a set of points in the xy-plane, determine the minimum area of any rectangle formed from ...
- 【LeetCode】963. Minimum Area Rectangle II 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 线段长+线段中心+字典 日期 题目地址:https: ...
- 【LeetCode】435. Non-overlapping Intervals 解题报告(Python)
[LeetCode]435. Non-overlapping Intervals 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemi ...
- 【LeetCode】397. Integer Replacement 解题报告(Python)
[LeetCode]397. Integer Replacement 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode.com/problems/inte ...
- 【LeetCode】376. Wiggle Subsequence 解题报告(Python)
[LeetCode]376. Wiggle Subsequence 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.c ...
随机推荐
- Bootstrap实战 - 瀑布流布局
讲 Bootstrap 基础的教程网上已经很多了,实际上 Bootstrap 中文网(bootcss.com)里的文档已经写的很详细了,但实战的案例却不多.这里用一些当前流行的网页布局为导向,使用 B ...
- 腾讯云联合中国信通院&作业帮等首发《降本之源-云原生成本管理白皮书》
在11月4日举办的2021腾讯数字生态大会云原生专场上,腾讯云联合中国信通院.作业帮等率先在国内重磅发布了<降本之源-云原生成本管理白皮书>(简称白皮书),基于腾讯云在业内最大规模的 Ku ...
- nodejs-Cluster模块
JavaScript 标准参考教程(alpha) 草稿二:Node.js Cluster模块 GitHub TOP Cluster模块 来自<JavaScript 标准参考教程(alpha)&g ...
- 对于HTML和XML的理解
1.什么是HTML??? HTML就是 超文本标记语言(超文本含义:超过文本 --图片 .视频.音频. 超链接) 2.HTML作用 把网页的信息格式化的展现,对网页信息进行规范化展示 连接(https ...
- MyBatis绑定Mapper接口参数到Mapper映射文件sql语句参数
一.设置paramterType 1.类型为基本类型 a.代码示例 映射文件: <select id="findShopCartInfoById" parameterType ...
- Linux目录结构和基础命令
Linux目录和基础命令 目录 Linux目录和基础命令 1 Linux目录结构 1.1 Linux文件名命令要求 1.2 文件的类型 2. 基础命令 2.1 ls 2.2 cd和pwd 2.3 命令 ...
- 【JS】toLocaleString 日期格式,千分位转换
https://blog.csdn.net/Seven521m/article/details/108866881 类似于c里printf(m%)的意思 可以指定整数最少位数,小数最少与最多位数,有效 ...
- 【C/C++】引用&的含义/语法/作为函数参数/函数返回值/本质/常量引用
含义 引用不产生副本,只是给原变量起了别名. 对引用变量的操作就是对原变量的操作. 基本语法 数据类型 &别名 = 原名 e.g. int a = 10; int &b = a; // ...
- Python enumerate():使用计数器简化循环
摘要:当您需要计数和迭代中的值时,Pythonenumerate()允许您编写 Pythonicfor循环.最大的优点enumerate()是它返回一个带有计数器和值的元组,因此您不必自己增加计数器. ...
- 在Eclipse中编写jQuery代码时产生的错误(连载)
1.Error:启动Eclipse中的服务,显示错误,端口号被占用 解决方法: 方式一:修改对应的端口号(实际情况实际处理) 方式二:在进程中关闭Eclispe重新打开即可(截图说明) 2.Error ...