技术标签: Problems leetcode解题指南 leetcode
给定在 xy 平面上的一组点,确定由这些点组成的任何矩形的最小面积,其中矩形的边不一定平行于 x 轴和 y 轴。
如果没有任何矩形,就返回 0。
示例 1:
输入:[[1,2],[2,1],[1,0],[0,1]]
输出:2.00000
解释:最小面积的矩形出现在 [1,2],[2,1],[1,0],[0,1] 处,面积为 2。
示例 2:
输入:[[0,1],[2,1],[1,1],[1,0],[2,0]]
输出:1.00000
解释:最小面积的矩形出现在 [1,0],[1,1],[2,1],[2,0] 处,面积为 1。
示例 3:
输入:[[0,3],[1,2],[3,1],[1,3],[2,1]]
输出:0
解释:没法从这些点中组成任何矩形。
示例 4:
输入:[[3,1],[1,1],[0,1],[2,1],[3,3],[3,2],[0,2],[2,3]]
输出:2.00000
解释:最小面积的矩形出现在 [2,1],[2,3],[3,3],[3,1] 处,面积为 2。
提示:
1 <= points.length <= 50
0 <= points[i][0] <= 40000
0 <= points[i][1] <= 40000
10^-5
的答案将视为正确结果。解题思路
首先想到的解法就是暴力破解,我们先找三个点,首先判断这三个点是不是可以构成直角三角形,如果可以的话,我们再去确定第四个点
我们要判断这个坐标是不是在数组中,如果在的话,我们就确定了一个矩形,那么我们就可以计算面积。以此类推,计算所有矩形的面积,去最后所有矩形面积的最小值即可。
class Solution:
def minAreaFreeRect(self, points):
"""
:type points: List[List[int]]
:rtype: float
"""
res = float('inf')
mem = set(map(tuple, points))
def dis(p1, p2):
return (p1[0]-p2[0])**2 + (p1[1] - p2[1])**2
for (x1, y1) in points:
for (x2, y2) in points:
if x1 == x2 and y1 == y2:
continue
for (x3, y3) in points:
d1 = dis((x1,y1), (x2,y2))
d2 = dis((x1,y1), (x3,y3))
d3 = dis((x2,y2), (x3,y3))
if d1 + d3 != d2:
continue
x4 = x1+x3-x2
y4 = y1+y3-y2
if (x4,y4) not in mem:
continue
area = pow(d1, 0.5) * pow(d3, 0.5)
if area > 0:
res = min(res, area)
return res if res != float('inf') else 0
但是这种做法超时了。还有一种暴力破解的思路,就是现将所有四个点的组合枚举出来,然后判断这四个点是不是可以构成矩形,如果可以的话,计算面积,取所有面积的最小值即可。关于如何判断矩形,可以看这篇判断四个点是否可以构成矩形(优雅的解法!!!)。有没有什么更好的解法呢?我们可以先取出三个点的组合,然后假设这三个点可以构成矩形(并且假设其中一组点是对角),再通过上列中的两个公式求解出第四个点的位置,最后通过向量点积确定是否存在直角,如果存在,那么这个矩形就存在,否则的话矩形不存在。
class Solution:
def minAreaFreeRect(self, points):
"""
:type points: List[List[int]]
:rtype: float
"""
points = set(map(tuple, points))
res = float('inf')
for p1, p2, p3 in itertools.combinations(points, 3):
p4 = p2[0] + p3[0] - p1[0], p2[1] + p3[1] - p1[1]
if p4 in points:
v21 = p2[0] - p1[0], p2[1] - p1[1]
v31 = p3[0] - p1[0], p3[1] - p1[1]
if abs(v21[0] * v31[0] + v21[1] * v31[1]) < 1e-5:
area = abs(v21[1] * v31[0] - v21[0] * v31[1])
if area < res:
res = area
return res if res != float('inf') else 0
通过向量计算的方式,我们加快了速度。但是这种算法依旧是O(n^3)
级别的,有没有更好的?对于最后一个例子
我们可以先取出连个点,然后计算两个点的中点,我们建立一个dict
存放相同斜率点的中点。
然后我们遍历dict
,然后从dict.val
中再取出两个点,这两个点一定来自于相同斜率的两边,我们再计算这两个点的斜率,如果和之前的边斜率相垂直,那么原来的两边(四个点)必能构成矩形。按照此法计算所有dict
中的值,最后取面积的最小值即可。
class Solution:
def minAreaFreeRect(self, points):
"""
:type points: List[List[int]]
:rtype: float
"""
points = [complex(*point) for point in sorted(points)]
mem = collections.defaultdict(list)
for p, q in itertools.combinations(points, 2):
mem[q - p].append((p + q) / 2)
res = float('inf')
for v1, mid_points in mem.items():
for a, b in itertools.combinations(mid_points, 2):
v2 = a - b
if abs(v1.real * v2.real + v1.imag * v2.imag) < 1e-5:
res = min(res, abs(v1) * abs(v2))
return res if res != float('inf') else 0
reference:
https://leetcode.com/problems/minimum-area-rectangle-ii/solution/
我将该问题的其他语言版本添加到了我的GitHub Leetcode
如有问题,希望大家指出!!!
目录vuecss微信小程序(到处找的,有的是上个月面试别问我的) vue vue双向绑定vue数据双向绑定原理vue的数据双向绑定主要通过Object.defineProperty()方法来进行数据劫持以及发布者-订阅模式来实现的1.实现一个监听器Observer,用来劫持并监听所有属性,如果有变动的,就通知订阅者。2.实现一个订阅者Watcher,可以收到属性的变化通知并执行相应的函数,从而更新视图。3.实现一个解析器Compile,可以扫描和解析每个节点的
appium和selenium的区别_appium和selenium区别
西门子S7-1500控制器模块6ES7516-3AN02-0AB06ES75184AP000AB06ES75184AX001AC06ES75173AP000AB06ES75163AN010AB06ES75152AM010AB06ES75131AL020AB06ES75111AK020AB06ES75121CK010AB06ES75111CK010AB06ES75162PN000AB06ES75121DK010AB06ES75101DJ010AB06ES_6es7513-1al02-0ab0
1.配置项目的jar包基础jar包必须配置,Jason和文件上传下载的jar包在需要使用时配置(如果使用到servlet时报错,则需要配置servlet-api.jar,tomcat安装时自带,在文件夹中复制即可)2.在web.xml中配置servlet<servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springfr_springmvc框架 如何给各个接口前面访问配置项目名
给定一个二维网格 board 和一个字典中的单词列表 words,找出所有同时在二维网格和字典中出现的单词。单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。示例:输入: words = ["oath","pea","eat","rain"] and board =[ ['o','..._前缀树搜索算法可以和什么方法结合使用
只有当数据的质量好才能保证数据分析的结果好。然后实际系统中的原始数据会因为很多原因出现数据错误,数据缺失,不一致等情况,所以需要对原始数据进行预处理,包括数据清洗,数据集成,数据归约,数据转换。目的:填充或删除缺失值,降低噪声与识别离群点。数据清洗的第一步偏差检测(数据的不一致性,字段过载),第二步纠正偏差1.缺失值处理(1)直接删除缺失属性的记录。(2)人工填写缺失值。(3)使用全局常量填写缺失值(4)使用属性的中心趋势度量值填写缺失值(中位数或均值)(5)使用与给定元组属于同一类的所有样本_等宽分箱法
node.js(李鹏周)、git就是一个命令行下运行的软件工具 属于一个版本管理工具node也可以用来做开发命令行工具 但主要还是服务器后台Node不是用来操作dom的 主要是用来做一些服务器级别的操作clear的意思7简单的http服务器08-发送响应一定要确定端口没有被占用 否则失效如果代码被..._node第一天
理解三大范式什么是三大范式:第一范式:当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。第二范式:如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。第三范式:设R是一个满足第一范式条..._学生信息课表,满足第二范式
GSONGSON是Google公司开发的用于解析json的类库。可以很轻松地让程序员将java对象转换成JSON格式,或者将JSON格式的对象转换成Java对象。使用方法很简单:首先,需要将GSON类库的jar包引入到自己的IDE中,本教程使用IDEA为例子。引入依赖即可,本次不引入依赖,学习一下IDEA怎么引入一个jar包。1.下载GSON的jar包GSON的github地址:https://github.com/google/gson/GSON的下载地址:https://search.ma_gson jar
2017考研国家线已经于3月15日出来了,接下来各考研院校线也将随后公布。为方便考生第一时间查询西北师范大学2017年招收硕士研究生复试分数线,研招网小编特此整理发布,希望对大家有所帮助。报考学科门类(专业或研究方向)或考生类型(代码)总分单科(满分=100分)单科(满分>100分)备注学术型哲学(01)2753553经济学(02)3254365法学(03)(不含马克思主义理论)300416...
《焊接过程的数值模拟》是2017年科学出版社出版的图书,作者是金成。书名焊接过程的数值模拟别名金成出版社科学出版社ISBN9787030551030焊接过程的数值模拟内容简介编辑语音焊接是一个涉及电弧物理、传质传热、力学、冶金与材料学等多物理场耦合的复杂过程,影响因素繁多。随着计算机科技的快速发展,焊接数值模拟技术得到了越来越广泛的关注和应用。《焊接过程的数值模拟》以“理论介绍一数..._焊接数值模拟的步骤
佳能用户,你是否知道通过免费的EOS Utility软件可以把电脑变成外置监视器并远程控制相机进行拍摄呢?本文我们就来深入了解一下这项功能。连接相机使用USB-A/V线将相机与电脑连接起来。这一点与从相机向电脑传输照片是一样的。连接之后要确保相机已经开机。打开EOS Utility打开EOS Utility软件,选择“相机选项/远程拍摄”,会出现一个小窗口。在菜单顶部,你可以看到当前的相机设置及电..._佳能摄像机webui控制