当前位置: 首页 > news >正文

详细介绍:LeetCode 391 完美矩形

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 代码解析
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

在做矩形覆盖的题目时,很多人第一反应就是「遍历 + 合并区间」,但 LeetCode 的 完美矩形 题目可没那么简单。它不仅要求所有小矩形刚好拼出一个大矩形,而且不能有重叠、不能有缝隙,就像拼图一样必须严丝合缝。本文会带你逐步拆解问题,分析为什么简单的遍历不够用,并给出一个基于 面积校验 + 顶点校验 的高效解法。

描述

题目给你一组小矩形,每个矩形由左下角 (xi, yi) 和右上角 (ai, bi) 表示,矩形都是和坐标轴平行的。现在你要判断这些矩形是否能 完美拼接成一个更大的矩形

判断标准主要有两个:

  1. 拼接后的整体区域必须是一个完整的大矩形。
  2. 小矩形之间不能重叠,也不能留下空隙。

换句话说,我们不仅要保证拼出来的总面积等于大矩形的面积,还要保证小矩形的边界刚好吻合。

实际场景类比:
可以想象一下装修时铺瓷砖:如果你要用一堆小方砖铺满一个长方形的地板,那么这堆砖必须正好覆盖整个地板,不能多也不能少,更不能有两块砖重叠。

题解答案

核心思路是 面积校验 + 顶点唯一性

  1. 面积校验:所有小矩形的面积和必须等于大矩形的面积。
  2. 顶点校验:大矩形的四个顶点必须只出现一次,其它所有中间拼接的点必须出现偶数次(因为它们会被相邻矩形共享)。

一旦两个条件同时满足,就说明所有矩形能完美拼成一个大矩形。

题解代码分析

下面是完整的 Swift 实现代码:

import Foundation
class PerfectRectangle {
func isRectangleCover(_ rectangles: [[Int]]) -> Bool {
var minX = Int.max, minY = Int.max
var maxX = Int.min, maxY = Int.min
var areaSum = 0
var points = Set<String>()func addOrRemovePoint(_ x: Int, _ y: Int) {let key = "\(x),\(y)"if points.contains(key) {points.remove(key)} else {points.insert(key)}}for rect in rectangles {let x1 = rect[0], y1 = rect[1]let x2 = rect[2], y2 = rect[3]// 更新外接矩形边界minX = min(minX, x1)minY = min(minY, y1)maxX = max(maxX, x2)maxY = max(maxY, y2)// 累加面积areaSum += (x2 - x1) * (y2 - y1)// 处理矩形四个顶点addOrRemovePoint(x1, y1)addOrRemovePoint(x1, y2)addOrRemovePoint(x2, y1)addOrRemovePoint(x2, y2)}// 计算外接矩形的面积let expectedArea = (maxX - minX) * (maxY - minY)if areaSum != expectedArea {return false}// 外接矩形的四个顶点let expectedPoints = ["\(minX),\(minY)","\(minX),\(maxY)","\(maxX),\(minY)","\(maxX),\(maxY)"]// 校验点集合是否只剩下四个顶点if points.count != 4 {return false}for p in expectedPoints {if !points.contains(p) {return false}}return true}}

代码解析

  1. 边界计算:通过遍历所有矩形,记录整个覆盖区域的最小 (x, y) 和最大 (x, y),得到大矩形的外接边界。

  2. 面积验证:小矩形的面积总和必须和外接矩形的面积一致。

  3. 顶点处理

    • 对每个小矩形的四个顶点执行「异或」式的操作:如果顶点第一次出现就加入集合,如果再次出现就删除。
    • 最终应该只剩下外接矩形的四个顶点。
  4. 返回结果:如果面积对上,顶点集合正确,就返回 true

示例测试及结果

let solver = PerfectRectangle()
print(solver.isRectangleCover([[1,1,3,3],[3,1,4,2],[3,2,4,4],[1,3,2,4],[2,3,3,4]]))
// 输出: true
print(solver.isRectangleCover([[1,1,2,3],[1,3,2,4],[3,1,4,2],[3,2,4,4]]))
// 输出: false
print(solver.isRectangleCover([[1,1,3,3],[3,1,4,2],[1,3,2,4],[2,2,4,4]]))
// 输出: false

结果解释:

  • 第一个示例,小矩形严丝合缝拼成大矩形,返回 true
  • 第二个示例有间隙,返回 false
  • 第三个示例有重叠,返回 false

时间复杂度

  • 遍历所有矩形一次,每个矩形只处理 4 个顶点。
  • 时间复杂度为 O(n),其中 n 是矩形的数量。

空间复杂度

总结

这道题如果直接用模拟的方法去拼接,复杂度会非常高,尤其是 n 可以达到两万的时候,根本不可行。

真正的突破点在于 把二维覆盖问题转化成面积 + 顶点唯一性验证

  • 面积保证了整体没有缝隙;
  • 顶点唯一性保证了没有重叠。

这种解法思路非常优雅,既避免了暴力模拟,又保证了正确性。日常开发中,如果你遇到「多个区域拼接是否能完美组成大区域」的需求,比如地图划分、UI 布局检查,其实也可以借鉴这种「全局面积 + 局部边界」的思路来解决。

http://www.hskmm.com/?act=detail&tid=24092

相关文章:

  • [NOI2025] 集合 题解
  • bi数据报表发送周期,周报和月报获取日期时间
  • 技术Leader的1-3-5沟通法则:向上管理的艺术 - 指南
  • cannot resolve method add in T 及 T 泛型类型生成Excel文件,区别是数据Model不同
  • 测试环境elasticSearch数据泄露排查
  • 深入解析:Spring boot中 限制 Mybatis SQL日志的大字段输出
  • 【AI时代速通QT】第九节:揭秘Qt编译全流程-从.pro材料到可执行程序
  • 考试心得5
  • javascript高级 - Ref
  • Solar9月赛wp - 场
  • 实用指南:深度解析Sora2:技术革命与创意产业的未来图景
  • 自动化安全工具的双刃剑:红队演练揭示安全响应盲区
  • Elastic Search 安装部署最全教程(Docker)
  • 详细介绍:图像分割:PyTorch从零开始实现SegFormer语义分割
  • 深入解析:Playwright同步、异步、并行、串行执行效率比较
  • 2025十一集训——Day2模拟赛
  • 2025十一集训——Day模拟赛
  • Qt纯代码实现智能安防集中管理平台/楼宇对讲管理系统/门禁管理/视频监控
  • 汉文博士词典库源文件已在 github 开放
  • 读人形机器人30未来20年
  • Flutter + Ollama:开启本地AI的全平台新纪元 —— 从零剖析一款现代化AI客户端的技能奥秘
  • 股票资料API接口全解析:从技术原理到多语言实战(含实时行情、MACD、KDJ等技术指标数据与API文档详解)
  • 产业园区招商团队快躺平了 - 智慧园区
  • 洛谷 P3545
  • 题解:AT_wtf22_day2_b The Greatest Two
  • 威胁狩猎实战:终端攻击行为分析与检测
  • 实用指南:基于Hadoop+Spark的人体体能数据分析与可视化系统开源实现
  • 英语_阅读_Water Sliding_待读
  • 实用指南:ArcGIS JSAPI 高级教程 - 高亮效果优化之开启使用多高亮样式
  • const在for用不了