0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一道比较有难度的完美矩形题

算法与数据结构 来源:算法与数据结构 作者:labuladong 2021-01-04 14:17 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

今天讲一道非常有意思,而且比较有难度的题目。

我们知道一个矩形有四个顶点,但是只要两个顶点的坐标就可以确定一个矩形了(比如左下角和右上角两个顶点坐标)。

来看看力扣第 391 题「完美矩形」,题目会给我们输入一个数组rectangles,里面装着若干四元组(x1,y1,x2,y2),每个四元组就是记录一个矩形的左下角和右上角顶点坐标。

也就是说,输入的rectangles数组实际上就是很多小矩形,题目要求我们输出一个布尔值,判断这些小矩形能否构成一个「完美矩形」。函数签名如下:

defisRectangleCover(rectangles:List[List[int]])->bool

所谓「完美矩形」,就是说rectangles中的小矩形拼成图形必须是一个大矩形,且大矩形中不能有重叠和空缺。

比如说题目给我们举了几个例子:

19b50fdc-4423-11eb-8b86-12bb97331649.png

1a1cb240-4423-11eb-8b86-12bb97331649.png

1a4475c8-4423-11eb-8b86-12bb97331649.png

这个题目难度是 Hard,如果没有做过类似的题目,还真做不出来。

常规的思路,起码要把最终形成的图形表示出来吧,而且你要有方法去判断两个矩形是否有重叠,是否有空隙,虽然可以做到,不过感觉异常复杂。

其实,想判断最终形成的图形是否是完美矩形,需要从「面积」和「顶点」两个角度来处理。

先说说什么叫从「面积」的角度。

rectangles数组中每个元素都是一个四元组(x1, y1, x2, y2),表示一个小矩形的左下角顶点坐标和右上角顶点坐标。

那么假设这些小矩形最终形成了一个「完美矩形」,你会不会求这个完美矩形的左下角顶点坐标(X1, Y1)和右上角顶点的坐标(X2, Y2)?

这个很简单吧,左下角顶点(X1, Y1)就是rectangles中所有小矩形中最靠左下角的那个小矩形的左下角顶点;右上角顶点(X2, Y2)就是所有小矩形中最靠右上角的那个小矩形的右上角顶点。

注意我们用小写字母表示小矩形的坐标,大写字母表示最终形成的完美矩形的坐标,可以这样写代码:

#左下角顶点,初始化为正无穷,以便记录最小值
X1,Y1=float('inf'),float('inf')
#右上角顶点,初始化为负无穷,以便记录最大值
X2,Y2=-float('inf'),-float('inf')

forx1,y1,x2,y2inrectangles:
#取小矩形左下角顶点的最小值
X1,Y1=min(X1,x1),min(Y1,y1)
#取小矩形右上角顶点的最大值
X2,Y2=max(X2,x2),max(Y2,y2)

这样就能求出完美矩形的左下角顶点坐标(X1, Y1)和右上角顶点的坐标(X2, Y2)了。

计算出的X1,Y1,X2,Y2坐标是完美矩形的「理论坐标」,如果所有小矩形的面积之和不等于这个完美矩形的理论面积,那么说明最终形成的图形肯定存在空缺或者重叠,肯定不是完美矩形。

代码可以进一步:

defisRectangleCover(rectangles:List[List[int]])->bool:
X1,Y1=float('inf'),float('inf')
X2,Y2=-float('inf'),-float('inf')
#记录所有小矩形的面积之和
actual_area=0
forx1,y1,x2,y2inrectangles:
#计算完美矩形的理论坐标
X1,Y1=min(X1,x1),min(Y1,y1)
X2,Y2=max(X2,x2),max(Y2,y2)
#累加所有小矩形的面积
actual_area+=(x2-x1)*(y2-y1)

#计算完美矩形的理论面积
expected_area=(X2-X1)*(Y2-Y1)
#面积应该相同
ifactual_area!=expected_area:
returnFalse

returnTrue

这样,「面积」这个维度就完成了,思路其实不难,无非就是假设最终形成的图形是个完美矩形,然后比较面积是否相等,如果不相等的话说明最终形成的图形一定存在空缺或者重叠部分,不是完美矩形。

但是反过来说,如果面积相同,是否可以证明最终形成的图形是完美矩形,一定不存在空缺或者重叠?

肯定是不行的,举个很简单的例子,你假想一个完美矩形,然后我在它中间挖掉一个小矩形,把这个小矩形向下平移一个单位。这样小矩形的面积之和没变,但是原来的完美矩形中就空缺了一部分,也重叠了一部分,已经不是完美矩形了。

综上,即便面积相同,并不能完全保证不存在空缺或者重叠,所以我们需要从「顶点」的维度来辅助判断。

记得小学的时候有一道智力题,给你一个矩形,切一刀,剩下的图形有几个顶点?答案是,如果沿着对角线切,就剩 3 个顶点;如果横着或者竖着切,剩 4 个顶点;如果只切掉一个小角,那么会出现 5 个顶点。

回到这道题,我们接下来的分析也有那么一点智力题的味道。

显然,完美矩形一定只有四个顶点。矩形嘛,按理说应该有四个顶点,如果存在空缺或者重叠的话,肯定不是四个顶点,比如说题目的这两个例子就有不止 4 个顶点:

1a955cfe-4423-11eb-8b86-12bb97331649.png

PS:我也不知道应该用「顶点」还是「角」来形容,好像都不太准确,本文统一用「顶点」来形容,大家理解就好~

只要我们想办法计算rectangles中的小矩形最终形成的图形有几个顶点,就能判断最终的图形是不是一个完美矩形了。

那么顶点是如何形成的呢?我们倒是一眼就可以看出来顶点在哪里,问题是如何让计算机,让算法知道某一个点是不是顶点呢?这也是本题的难点所在。

看下图的四种情况:

1ae13f5c-4423-11eb-8b86-12bb97331649.jpg

图中画红点的地方,什么时候是顶点,什么时候不是顶点?显然,情况一和情况三的时候是顶点,而情况二和情况四的时候不是顶点。

也就是说,当某一个点同时是 2 个或者 4 个小矩形的顶点时,该点最终不是顶点;当某一个点同时是 1 个或者 3 个小矩形的顶点时,该点最终是一个顶点。

注意,2 和 4 都是偶数,1 和 3 都是奇数,我们想计算最终形成的图形中有几个顶点,也就是要筛选出那些出现了奇数次的顶点,可以这样写代码:

defisRectangleCover(rectangles:List[List[int]])->bool:
X1,Y1=float('inf'),float('inf')
X2,Y2=-float('inf'),-float('inf')

actual_area=0
#哈希集合,记录最终图形的顶点
points=set()
forx1,y1,x2,y2inrectangles:
X1,Y1=min(X1,x1),min(Y1,y1)
X2,Y2=max(X2,x2),max(Y2,y2)

actual_area+=(x2-x1)*(y2-y1)
#先算出小矩形每个点的坐标
p1,p2=(x1,y1),(x1,y2)
p3,p4=(x2,y1),(x2,y2)
#对于每个点,如果存在集合中,删除它;
#如果不存在集合中,添加它;
#在集合中剩下的点都是出现奇数次的点
forpin[p1,p2,p3,p4]:
ifpinpoints:points.remove(p)
else:points.add(p)

expected_area=(X2-X1)*(Y2-Y1)
ifactual_area!=expected_area:
returnFalse

returnTrue

这段代码中,我们用一个points集合记录rectangles中小矩形组成的最终图形的顶点坐标,关键逻辑在于如何向points中添加坐标:

如果某一个顶点p存在于集合points中,则将它删除;如果不存在于集合points中,则将它插入。

这个简单的逻辑,让points集合最终只会留下那些出现了 1 次或者 3 次的顶点,那些出现了 2 次或者 4 次的顶点都被消掉了。

那么首先想到,points集合中最后应该只有 4 个顶点对吧,如果len(points) != 4说明最终构成的图形肯定不是完美矩形。

但是如果len(points) == 4是否能说明最终构成的图形肯定是完美矩形呢?也不行,因为题目并没有说rectangles中的小矩形不存在重复,比如下面这种情况:

1b0dfa42-4423-11eb-8b86-12bb97331649.jpg

下面两个矩形重复了,按照我们的算法逻辑,它们的顶点都被消掉了,最终是剩下了四个顶点;再看面积,完美矩形的理论坐标是图中红色的点,计算出的理论面积和实际面积也相同。但是显然这种情况不是题目要求完美矩形。

所以不仅要保证len(points) == 4,而且要保证points中最终剩下的点坐标就是完美矩形的四个理论坐标,直接看代码吧:

defisRectangleCover(rectangles:List[List[int]])->bool:
X1,Y1=float('inf'),float('inf')
X2,Y2=-float('inf'),-float('inf')

points=set()
actual_area=0
forx1,y1,x2,y2inrectangles:
#计算完美矩形的理论顶点坐标
X1,Y1=min(X1,x1),min(Y1,y1)
X2,Y2=max(X2,x2),max(Y2,y2)
#累加小矩形的面积
actual_area+=(x2-x1)*(y2-y1)
#记录最终形成的图形中的顶点
p1,p2=(x1,y1),(x1,y2)
p3,p4=(x2,y1),(x2,y2)
forpin[p1,p2,p3,p4]:
ifpinpoints:points.remove(p)
else:points.add(p)
#判断面积是否相同
expected_area=(X2-X1)*(Y2-Y1)
ifactual_area!=expected_area:
returnFalse
#判断最终留下的顶点个数是否为4
iflen(points)!=4:returnFalse
#判断留下的4个顶点是否是完美矩形的顶点
if(X1,Y1)notinpoints:returnFalse
if(X1,Y2)notinpoints:returnFalse
if(X2,Y1)notinpoints:returnFalse
if(X2,Y2)notinpoints:returnFalse
#面积和顶点都对应,说明矩形符合题意
returnTrue

这就是最终的解法代码,从「面积」和「顶点」两个维度来判断:

1、判断面积,通过完美矩形的理论坐标计算出一个理论面积,然后和rectangles中小矩形的实际面积和做对比。

2、判断顶点,points集合中应该只剩下 4 个顶点且剩下的顶点必须都是完美矩形的理论顶点。

说实话,如果没做过,这种特性真不是一时半会能想到的,但是看过一遍没问题了,你学会了吗?

责任编辑:xj

原文标题:这道「完美矩形」给我整不会了…

文章出处:【微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66838
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73148

原文标题:这道「完美矩形」给我整不会了…

文章出处:【微信号:TheAlgorithm,微信公众号:算法与数据结构】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    不间断电源(UPS):电力保障的“最后一道防线”

    (UninterruptiblePowerSupply,简称UPS)作为电力保障的“最后一道防线”,通过储能装置与智能转换技术,在市电中断时实现零切换时间供电,成为现代社会的“电力守护者”。、UP
    的头像 发表于 10-29 09:02 400次阅读
    不间断电源(UPS):电力保障的“最后<b class='flag-5'>一道</b>防线”

    铅酸蓄电池在线监测:为关键基础设施筑牢“最后一道防线”

    在数据中心、通信基站、轨道交通等关键应用场景中,蓄电池组往往是供电系统的“最后一道屏障”。旦蓄电池出现故障,可能导致系统断电、数据丢失甚至设备损坏,带来不可估量的经济损失和安全风险。因此,对蓄电池
    的头像 发表于 09-23 09:31 377次阅读
    铅酸蓄电池在线监测:为关键基础设施筑牢“最后<b class='flag-5'>一道</b>防线”

    顶坚国产防爆手持终端如何成为石化企业安全生产的第一道防线

    顶坚国产防爆手持终端之所以能成为石化企业安全生产的第一道防线,源于其通过防爆设计、功能集成、实时交互与系统协同,从物理安全、功能安全、管理安全、应急安全等维度,覆盖了安全生产的全流程(预防、监测
    的头像 发表于 08-26 10:31 626次阅读
    顶坚国产防爆手持终端如何成为石化企业安全生产的第<b class='flag-5'>一道</b>防线

    【嘉楠堪智K230开发板试用体验】高校竞赛-2025电赛-E

    01Studio官方店-淘宝网 2025电赛题目汇总 勘智开发者社区(包含产品资料) 题目分析 E 简易自行瞄准装置 概述 题目要求识别矩形并获取矩形中的些特征点供激光视觉模块追
    发表于 08-21 15:32

    【赛知多少】 紫光同创赛答疑专场|2025年全国大学生嵌入式芯片与系统设计竞赛FPGA赛道

    紫光同创赛道答疑专场来啦!2025年全国大学生嵌入式芯片与系统设计竞赛报名已拉开帷幕,FPGA赛道的挑战与创新并存。近期,我们收到许多关于赛的咨询,小眼睛科技团队第时间整理了大家的疑问,并带来
    的头像 发表于 08-06 11:02 3245次阅读
    【赛<b class='flag-5'>题</b>知多少】 紫光同创赛<b class='flag-5'>题</b>答疑专场|2025年全国大学生嵌入式芯片与系统设计竞赛FPGA赛道

    聚徽制造业专属工业触摸屏:精准控制每一道工序,提升生产精度

    在制造业竞争日益激烈的当下,产品质量与生产效率成为企业立足市场的关键,而生产精度则是保障产品质量的核心要素。制造业专属工业触摸屏凭借其独特的功能与技术优势,深度融入生产的每一道工序,实现对生
    的头像 发表于 05-16 15:50 565次阅读

    水文监测中的双轨缆小车和铅鱼缆小车

    一道坚实的科技防线,那么这两个设备有什么区别呢,原理又是怎么样的呢?本文将探究竟。         双轨缆小车:通过两根平行的轨道来引导小车的运行,利用电机或其他动力装置驱动小车在轨道上移动,小车通常配备有滑轮或滚轮,与
    的头像 发表于 04-11 15:15 758次阅读
    水文监测中的双轨缆<b class='flag-5'>道</b>小车和铅鱼缆<b class='flag-5'>道</b>小车

    成品电池综合测试仪:电池品质的最后一道把关人

    综合测试仪便成为了电池生产线上的“最后一道把关人”,为电池品质保驾护航。 成品电池综合测试仪的重要性 成品电池综合测试仪,是种集多种测试功能于体的专业设备,能够对电池进行全面的性能测试和评估。从电池的容量、
    的头像 发表于 03-18 14:30 555次阅读

    难度PCB不再难!捷多邦揭秘PCB制作难度层级

    。 简单型PCB 简单型PCB通常指的是单面板或双面板,它们的设计相对简单,线路层数较少,元件密度低。这类PCB多用于些基础的电子设备,如计算器、简单的家用电器等。由于设计和制作难度较低,它们是电子工程师入门学习的好选择。 中等难度
    的头像 发表于 03-05 17:04 1164次阅读

    英特尔的开发板评测

    Linux系统,测试比较方便,虽然Windows+Python代码也可以开发,搞点难度的Ubuntu+     配置下OpenVINO ,参考手册。这个主要后面写代码和转模型用。但是我用C++写代码
    的头像 发表于 01-24 09:37 1622次阅读
    英特尔的开发板评测

    输入电压达到正负5v、精度比较高最好是12bit以上的,六通的ADC芯片般选哪几种?

    输入电压达到正负5v、精度比较高最好是12bit以上的,六通的ADC芯片般选哪几种,因为ADC之后是直接接FPGA处理的、最好是那种ADC芯片好呢、性能越好越好、
    发表于 01-22 06:47

    为什么选择日晟万欣矩形连接器?

    日晟万欣始终秉持高新技术企业“质量为本、客户至上”的经营理念,为中国电子行业贡献着高质量的产品和优质服务。日晟万欣产品线涵盖了多类型电子连接器,如矩形高速高密连接器、圆形推拉自锁连接器,线对板连接器
    的头像 发表于 01-07 17:59 856次阅读
    为什么选择日晟万欣<b class='flag-5'>矩形</b>连接器?

    硬件工程师面试常考的一道,讲讲运算放大器的增益带宽积

    Part 01 前言 想要学好运算放大器电路,个绕不过的参数就是增益带宽积,只有理解了增益带宽积,才能真正理解运算放大器电路的增益与带宽的关系。什么是增益带宽积呢?英文名字叫GBP或GBW
    的头像 发表于 12-27 08:13 6794次阅读
    硬件工程师面试常考的<b class='flag-5'>一道</b><b class='flag-5'>题</b>,讲讲运算放大器的增益带宽积

    ADS131E08输入信号后都叠加在矩形波上,为什么?

    ,跳变大小为47000左右,ads配置为8通24位采样16khz,输入信号后都叠加在矩形波上 这是输入正弦信号的图形,都是叠加在矩形波上,模拟前端进入adc之前信号没问题,不知道是什么原因后有
    发表于 12-18 06:36

    【「大话芯片制造」阅读体验】+跟着本书”参观“半导体工厂

    是什么? 难道是很多工艺会接触危险化学品,为了今次情况处理吗? 配套设施,通过这里才知道氮气般是现场生产的,还有就是配套超纯水供给很重要,之前就有了解过超纯水清洗是很重要的一道工艺。 书中
    发表于 12-16 22:47