LeetCode | 391.完美矩形

news2025/1/16 5:36:12

给你一个数组 rectangles ,其中 rectangles[i] = [xi, yi, ai, bi] 表示一个坐标轴平行的矩形。这个矩形的左下顶点是 (xi, yi) ,右上顶点是 (ai, bi)

如果所有矩形一起精确覆盖了某个矩形区域,则返回 true ;否则,返回 false

示例 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],[2,2,4,4]]
输出:false
解释:因为中间有相交区域,虽然形成了矩形,但不是精确覆盖。

提示:

  • 1 <= rectangles.length <= 2 * 104
  • rectangles[i].length == 4
  • -105 <= xi, yi, ai, bi <= 105

思路:
方案一:扫描线的思想
一个完美矩形的充要条件为:对于完美矩形的每一条非边缘的竖边,都「成对」出现(存在两条完全相同的左边和右边重叠在一起);对于完美矩形的两条边缘竖边,均独立为一条连续的(不重叠)的竖边。

如图(红色框的为「完美矩形的边缘竖边」,绿框的为「完美矩形的非边缘竖边」):
在这里插入图片描述
首尾相连的两条竖线(要同为左边或右边)看成一条
绿色:非边缘竖边必然有成对的左右两条完全相同的竖边重叠在一起;
红色:边缘竖边由于只有单边,必然不重叠,且连接成一条完成的竖边。

将每个矩形 rectangles[i] 看做两条竖直方向的边,使用 (x, y1, y2) 的形式进行存储(其中 y1 代表该竖边的下端点,y2 代表竖边的上端点),同时为了区分是矩形的左边还是右边,再引入一个标识位,即以四元组 (x, y1, y2, flag) 的形式进行存储。
保存所有竖边,按 x 从小到大,若 x 相等按 y1 从小到大进行排序。

遍历所有竖边。每次处理 x 坐标相同的一批竖边,判断是否符合条件

// 时间复杂度O(nlogn)
bool isRectangleCover(vector<vector<int>>& rectangles) {
    int n = rectangles.size() * 2;
    vector<vector<int>> rs;
    for (auto &rect : rectangles) {
        rs.push_back({rect[0], rect[1], rect[3], 1});
        rs.push_back({rect[2], rect[1], rect[3], -1});
    }
    sort(rs.begin(), rs.end(), [](vector<int>& a, vector<int> &b) -> bool {
        return a[0] < b[0] || (a[0] == b[0] && a[1] < b[1]);
    });

    vector<vector<int>> l1, l2;
    for (int l = 0; l < n;) {
        int r = l;
        l1.clear();
        l2.clear();
        while (r < n && rs[r][0] == rs[l][0]) { // 找到横坐标相同的线
            r++;
        }
        for (int i = l; i < r; i++) { // 处理横坐标相同的线
            vector<int> cur = {rs[i][1], rs[i][2]};
            auto &lis = rs[i][3] == 1 ? l1 : l2;
            if (lis.empty()) {
                lis.push_back(cur);
            } else {
                vector<int> &prev = lis.back();
                if (cur[0] < prev[1]) { // 当前线的下端 y 坐标小于上一根线的上端的 y 坐标
                    return false;
                } else if (cur[0] == prev[1]) { // 当前线的下端 y 坐标等于上一根线的上端的 y 坐标,合并为一条线
                    prev[1] = cur[1];
                } else {
                    lis.push_back(cur); // 当前线和上一根线之间空了一块,也是有可能的
                }
            }
        }
        if (l > 0 && r < n) { // 非边缘竖边
            if (l1.size() != l2.size()) 
                return false;
            for (int i = 0; i < l1.size(); i++) {
                if (l1[i][0] != l2[i][0] || l1[i][1] != l2[i][1])
                    return false;
            }
        } else { // 边缘竖边
            if (l1.size() + l2.size() != 1) {
                return false;
            }
        }
        l = r;
    }
    return true;
}

方案二:用点来表示整幅图。
每个矩形的左下角值为 1,左上角值为 -1,右下角值为 -1,右上角值为 1。空白区域的值为 0
在这里插入图片描述
图中红色方框内的顶点值的和都为 0

一个完美矩形,除了最外面四个角以外,其它所有的顶点和都为0。
遍历所有矩形的顶点,计算顶点和。当只有 4 个不为 0 的顶点且这 4 个顶点必须是 1 或 -1 时,矩形是完美矩形。

// O(n)的时间复杂度
bool isRectangleCover(vector<vector<int>>& rectangles) {
    unordered_map<long long, int> mark;
    const long long N = 1000000; // 用单个值表示坐标,用 x 乘一个大于 y 的取值范围的值,然后加 y
    for (auto &rect : rectangles) {
        int x1 = rect[0], y1 = rect[1];
        int x2 = rect[2], y2 = rect[3];
        mark[x1 * N + y1]++; // 左下角是 1
        mark[x1 * N + y2]--; // 左上角是 -1
        mark[x2 * N + y1]--; // 右下角是 -1
        mark[x2 * N + y2]++; // 右上角是 1;
    }
    int n_mark = 0;
    for (auto &ptr : mark) {
        if (ptr.second != 0) {
            if (abs(ptr.second) != 1) {
                return false;
            }
            n_mark++;
        }
    }
    return n_mark == 4;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/24132.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Matlab的合成孔径雷达模拟陆地场景(附源码)

目录 一、生成模拟地形 二、指定搜救系统和场景 三、定义地表反射率 四、配置雷达收发器 4.1 生成数据多维数据集 4.2 可视化 SAR 数据 五、总结 六、程序 合成孔径雷达&#xff08;SAR&#xff09;系统使用平台运动来模拟更长的孔径&#xff0c;以提高跨距离分辨率。S…

【半监督图像分割】2021-CPS CVPR

文章目录【半监督图像分割】2021-CPS CVPR1. 简介1.1 简介1.2 相关工作1.3 创新2. 网络2.1 网络架构2.2 Loss2.3 实验3. 代码【半监督图像分割】2021-CPS CVPR 论文题目&#xff1a;Semi-Supervised Semantic Segmentation with Cross Pseudo Supervision 中文题目&#xff1a;…

【第四部分 | JavaScript 基础】3:函数、作用域与预解析、对象

目录 | 函数 声明与调用 参数 返回值 arguments&#xff08;JS特有知识点&#xff09; 命名函数 和 匿名函数 | 作用域 全局和局部、JS5没有块级作用域 就近原则&#xff1a;作用域链 | 预解析&#xff08;重要&#xff09; 导论&#xff1a;四种语句位置导致的现象 …

安装TPDSS

TPDSS使用前电脑必须安装jdk。如若jdk安装完毕&#xff0c;则忽略第一步 第一步&#xff1a;jdk jdk安装完毕后控制面板会出现java字样 jdk安装完毕后&#xff0c;配置环境变量进行生效 1、进入到刚才安装时选择的文件夹&#xff0c;选中上方文件的路径&#xff0c;鼠标右键&…

全国各省产业结构协调-高级化、合理化指标(2000-2020年)

全国各省产业结构协调-高级化、合理化指标&#xff08;2000-2020年&#xff09; 1、时间&#xff1a;2000-2020年 2、包括&#xff1a;30个省份不含西藏 3、来源&#xff1a;统计NJ和国家统计J 4、指标包括&#xff1a; 原始数据&#xff1a;地区生产总值(亿元)、就业人员…

【软件测试】资深测试是如何火速入坑的?测试任务艰巨无从下手?

目录&#xff1a;导读一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;如何快速融入项目团队? 熟悉…

leetcode 1926. Nearest Exit from Entrance in Maze(迷宫最近的出口)

Input: maze [[“”,“”,“.”,“”],[“.”,“.”,“.”,“”],[“”,“”,“”,“.”]], entrance [1,2] Output: 1 Explanation: There are 3 exits in this maze at [1,0], [0,2], and [2,3]. Initially, you are at the entrance cell [1,2]. You can reach [1,0] by …

大模型产业化有四个关键,昇腾AI推动“AI+遥感”打了个样

文|智能相对论 作者|夜远风 农业卫星在太空“拍下”地面这张“照片”&#xff0c;地面根据这些图像数据&#xff0c;结合气象情况等&#xff0c;通过AI算法就准确地“算”出了农作物的长势状况&#xff0c;给地方政府、种地农民以参考。 &#xff08;图&#xff1a;农业用地的…

uni-app入门:页面布局之window和tabbar

1.window 2.tabbar 3.全局配置与局部页面配置 前言 每个页面按照结构可以分成三部分:window page tabbar.其中window和tabbar一般比较固定&#xff0c;page是平常业务开展的主要载体&#xff0c;根据业务需求进行页面配置。下面主要讲一下window和tabbar。 1.window…

【苹果相册】苹果推从新建的私钥CSR文件Profile还分为开发和分发

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

A-Level经济例题解析及练习

今日知识点&#xff1a; Externality and Government Intervention 例题 Externality and Government Intervention Acme and US Electric run coal-burning power plants. Each emits 40 tons of sulphur dioxide per month, total emissions 80 tons/month. Goal: Redu…

EXCEL函数

1.文本函数 1.2 LEFT() 概念&#xff1a;从文本字符串的第一个字符开始返回指定个数的字符。 例子&#xff1a;编辑此文本&#xff1a;忍一时风平浪静&#xff0c;退一步越想越气。 此处的H1即代表该文本&#xff0c;下面函数举例同样如此&#xff1a; 操作&#xff1a;LEFT(…

Magisk搞机器记录(小米Mix3)

背景 最近咸鱼入手了一块8256的小米Mix3手机&#xff0c;于是开始进行愉快的搞机之旅。笔者也是第一次玩&#xff0c;查阅了很多资料&#xff0c;如有错误的地方&#xff0c;还请大佬们指出来。 调研 经过大概的了解&#xff0c;大概就是解锁&#xff0c;获取Root权限&#…

机器学习笔记之高斯分布(五)推断任务之边缘概率分布与条件概率分布

机器学习笔记之高斯分布——推断任务之边缘概率分布与条件概率分布引言回顾&#xff1a;卡尔曼滤波高斯分布与线性计算的相关定理任务目标与推导过程任务目标求解边缘概率分布求解条件概率分布引言 上一节介绍了高斯分布概率模型相关的推断问题&#xff0c;并详细介绍了给定联…

RabbitMQ系列【12】惰性队列

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言设置为惰性队列内存开销对比前言 默认情况下&#xff0c;当生产者将消息发送到 RabbitMQ 的时候&#xff0c;队列中的消息会尽可能的存储在内存之中&#xff0c;这样可以更加快速的将消息发…

CTFHub技能树 Web-SQL注入详解

文章目录0x01 整数型注入0x02 字符型注入0x03 报错注入0x04 布尔盲注0x05 时间盲注0x06 MySql结构0x07 Cookie注入0x08 空格绕过0x09 UA注入0x10 Refer注入总结摘抄0x01 整数型注入 解题WP 第一步 尝试闭合点 第二步 判断列数 id1 order by 2 页面正常 id1 order by 3 页面…

C语言中的文件操作

在今天的文章中&#xff0c;我将要讲解C语言里的文件操作的详细知识。 目录1.为什么使用文件2.什么是文件2.1程序文件2.2数据文件2.3文件名3.文件的打开和关闭3.1文件指针3.2文件的打开和关闭3.2.1 fopen函数3.2.2 fclose函数3.2.3 文件的打开方式4.文件的顺序读写4.1 文件输入…

高通量筛选——离子化合物

上线离子通道筛选平台&#xff0c;提供形式多样的高表达细胞系的离子通道检测及新药临床前离子通道作用评价服务。 离子通道离子通道 (Ion Channel) 是一类跨膜的大分子孔道蛋白&#xff0c;可允许特定类型离子在电化学梯度驱动下穿过细胞膜&#xff0c;从而完成信号传导、细…

罗丹明PEG巯基,Rhodamine PEG Thiol,RB-PEG-SH

产品名称&#xff1a;罗丹明PEG巯基 英文名称&#xff1a;Rhodamine PEG Thiol&#xff0c;RB-PEG-SH 罗丹明B-PEG巯基&#xff08;RB-PEG-SH&#xff09;可以用来修饰蛋白质、多肽以及其他材料或者小分子。马来酰亚胺和巯基&#xff08;-SH&#xff09;在PH6.5-7.5很容易形成…

JAVA maven

Maven基础 Maven的本质是一个项目管理工具&#xff0c;将项目开发和管理过程抽象成一个项目对象模型&#xff08;POM&#xff09; POM(Project Object Model&#xff09;&#xff1a;项目对象模型。 项目对象模型&#xff08;POM&#xff09;需要加载pom.xml来确定项目&#x…