56. 合并区间(力扣LeetCode)

文章目录

  • 56. 合并区间
    • 题目描述
    • 思路
    • 贪心算法
      • 方法一:直接在res中修改
        • 代码逻辑梳理:
      • 方法二:在原数组中插入一个超出题目范围的数组
        • 代码逻辑梳理:

56. 合并区间

题目描述

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。

提示:

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104

思路

本题的本质其实还是判断重叠区间问题。

大家如果认真做题的话,话发现和我们刚刚讲过的452. 用最少数量的箭引爆气球和 435. 无重叠区间都是一个套路。

这几道题都是判断区间重叠,区别就是判断区间重叠后的逻辑,本题是判断区间重贴后要进行区间合并。

所以一样的套路,先排序,让所有的相邻区间尽可能的重叠在一起,按左边界,或者右边界排序都可以,处理逻辑稍有不同。

按照左边界从小到大排序之后,如果 intervals[i][0] <= intervals[i - 1][1]intervals[i]的左边界 <= intervals[i - 1]的右边界,则一定有重叠。(本题相邻区间也算重贴,所以是<=)

这么说有点抽象,看图:(注意图中区间都是按照左边界排序之后了)

在这里插入图片描述
知道如何判断重复之后,剩下的就是合并了,如何去模拟合并区间呢?

其实就是用合并区间后左边界和右边界,作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。

贪心算法

方法一:直接在res中修改

这段代码是C++语言编写的,用于解决合并重叠区间的问题。下面是对这段代码的详细注释:

// 定义Solution类
class Solution {
public:
    // 静态比较函数,用于sort函数中,按区间的起始位置升序排序
    // 如果a的起始位置小于b的起始位置,则返回true
    static bool cmp(vector<int> a, vector<int> b) {
        return a[0] < b[0];
    }

    // 合并区间的主要功能函数
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        // 存储最终合并后的区间数组
        vector<vector<int>> res;
        // 首先,根据区间的起始位置,使用自定义的比较函数cmp对区间进行排序
        sort(intervals.begin(), intervals.end(), cmp);
        // 将排序后的第一个区间添加到结果数组中,作为合并的起点
        res.push_back(intervals[0]);
        
        // 从第二个区间开始遍历排序后的区间数组
        for(int i = 1; i < intervals.size(); i++) {
            // 如果当前区间的起始位置小于等于结果数组中最后一个区间的结束位置,
            // 则说明当前区间与结果数组中的最后一个区间有重叠
            if(intervals[i][0] <= res.back()[1])
                // 更新结果数组中最后一个区间的结束位置为当前区间和最后一个区间结束位置的较大值
                // 以此合并重叠的区间
                res.back()[1] = max(res.back()[1], intervals[i][1]);
            else
                // 如果当前区间与结果数组中的最后一个区间没有重叠,
                // 则直接将当前区间添加到结果数组中
                res.push_back(intervals[i]);
        }
        // 返回合并后的区间数组
        return res;
    }
};
代码逻辑梳理:
  1. 排序:首先通过sort函数和自定义的比较函数cmp对输入的区间数组进行排序,确保区间是按照起始位置升序排列的。这是解决问题的关键步骤,因为只有排序后,我们才能通过顺序遍历来识别哪些区间是重叠的。

  2. 初始化:将排序后的第一个区间直接添加到结果数组res中。这是因为,不管后面的区间是否与它重叠,第一个区间总是需要被包含在最终的结果中。

  3. 遍历合并:从第二个区间开始遍历,对每个区间,检查它的起始位置是否小于等于结果数组中最后一个区间的结束位置。如果是,说明当前区间与结果数组中的最后一个区间重叠,此时需要更新结果数组中最后一个区间的结束位置为两个区间结束位置的较大值,以此来合并区间。如果不重叠,直接将当前区间添加到结果数组中。

  4. 返回结果:经过遍历和条件判断后,所有重叠的区间都被合并,函数返回最终的结果数组。

这种方法的优点是逻辑清晰,且只需要一次遍历就可以完成合并,效率较高。

方法二:在原数组中插入一个超出题目范围的数组

这段代码是使用C++语言编写的,用于解决合并区间的问题。下面是这段代码的详细注释:

// 定义Solution类
class Solution {
public:
    // 静态比较函数,用于sort函数中,按区间的起始位置升序排序
    // 如果a的起始位置小于b的起始位置,则返回true
    static bool cmp(vector<int> a,vector<int> b)
    {
        return a[0]<b[0];
    }
    // 合并区间的主要函数
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        // 存储最终合并后的区间结果
        vector<vector<int>> res;
        // 首先,根据区间的起始位置,使用自定义的比较函数cmp对区间进行排序
        sort(intervals.begin(),intervals.end(),cmp);
        // 为了处理方便,在intervals的末尾添加一个超出范围的区间[10001,10001],
        // 这样在遍历时就不需要特殊处理最后一个区间
        intervals.push_back({10001,10001});
        
        // 遍历排序后的区间
        for(int i=0;i<intervals.size()-1;i++)
        {
            // 如果当前区间的结束位置不小于下一个区间的起始位置,说明两个区间有重叠
            if(intervals[i+1][0]<=intervals[i][1])
            {
                // 更新下一个区间的结束位置为当前区间和下一个区间结束位置的较大值
                // 这样做是为了合并重叠的区间
                intervals[i+1][1]=max(intervals[i+1][1],intervals[i][1]);
                // 更新下一个区间的起始位置为当前区间的起始位置
                intervals[i+1][0]=intervals[i][0];
            }
            else
            {
                // 如果没有重叠,则将当前区间加入到结果中
                res.push_back(intervals[i]);
            }
        }
        // 返回合并后的区间集合
        return res;
    }
};
代码逻辑梳理:
  1. 排序:首先,通过自定义的排序函数cmp将所有区间根据起始位置进行升序排序。这是合并区间问题的核心步骤之一,它可以让我们在后续遍历时更容易判断区间是否重叠。

  2. 遍历:遍历排序后的区间数组。对于每个区间,检查它与下一个区间是否重叠(即当前区间的结束位置不小于下一个区间的起始位置)。

  3. 合并处理:如果两个区间重叠,更新下一个区间的起始和结束位置,将它们合并为一个区间。这里通过修改下一个区间的起始和结束位置来实现合并,而非直接操作当前区间,是为了简化逻辑,因为通过前面的排序保证了遍历时区间是按起始位置顺序来的。

  4. 添加非重叠区间:如果两个区间不重叠,将当前区间加入到结果集中。

  5. 处理边界:通过在intervals末尾添加一个超出范围的区间[10001,10001],简化了最后一个区间的处理逻辑,避免了在循环中额外判断是否为最后一个区间。这个超出范围的区间不会被加入最终结果,因为它是在遍历结束前添加的,仅用作逻辑上的辅助。

这种方法直接在原数组上进行操作,减少了空间复杂度,但修改了输入数组,这在某些情况下可能不是最佳做法。在实际应用中,根据是否允许修改输入数组来选择合适的方法。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis-Plus分页接口实现教程:Spring Boot中如何编写分页查询

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

http响应练习—在服务器端渲染html(SSR)

一、什么是服务器端渲染&#xff08;SSR&#xff09; 简单说&#xff0c;就是在服务器上把网页生成好&#xff0c;整个的HTML页面生成出来&#xff0c;生成出的页面已经包含了所有必要的数据和结构信息&#xff0c;然后直接发给浏览器进行展现。 二、例题 要求搭建http服务&a…

白板手推公式性质 AR模型 时间序列分析

白板手推公式性质 AR模型 时间序列分析 视频讲解&#xff1a;https://www.bilibili.com/video/BV1D1421S76v/?spm_id_from.dynamic.content.click&vd_source6e452cd7908a2d9b382932f345476fd1 B站对应视频讲解(白板手推公式性质 AR模型 时间序列分析)

Java 学习和实践笔记(49):用javabean和一维数组的方式来存储表格数据

还是存储下面这个表格的数据&#xff0c;但使用另一种方法来做。 用javabean和一维数组的方法来做&#xff0c;示例代码如下&#xff1a; /*先创建一个类&#xff0c;其实就是创建好一个只有各属性列的空表格*/ class Employees {private int id;private String name;private …

【Linux进阶之路】理解UDP,成为TCP。

前言 学了TCP 和UDP之后&#xff0c;感觉UDP就像是初入职场的年轻人&#xff0c;两耳不闻 “窗外事”&#xff0c;只管尽力地把自己的事情做好&#xff0c;但收获的却是不可靠&#xff0c;而TCP更像是涉世极深的"职场老油条"&#xff0c;给人的感觉就是 “城府极深&a…

H12-831_338

多选题338、某园区部署OSPF实现网络互通&#xff0c;其中R2的LSDB如图所示。以下关于该LSDB信息的描述&#xff0c;错误的有哪些项? A.此时R4不能访间地址10.1.35.5/24&#xff0c;因为R4所在的Area l内没有泛洪R3-R5互联网段路由信息 B.Area l内无3类LSA&#xff0c;有7类1SA…

【jenkins+cmake+svn管理c++项目】jenkins回传文件到svn(windows)

书接上文&#xff1a;创建一个项目 在经过cmakemsbuild顺利生成动态库之后&#xff0c;考虑到我一个项目可能会生成多个动态库&#xff0c;它们分散在build内的不同文件夹&#xff0c;我希望能将它们收拢到一个文件夹下&#xff0c;并将其回传到svn。 一、动态库移位—cmake实…

C# wpf 嵌入wpf控件

WPF Hwnd窗口互操作系列 第一章 嵌入Hwnd窗口 第二章 嵌入WinForm控件 第三章 嵌入WPF控件&#xff08;本章&#xff09; 文章目录 WPF Hwnd窗口互操作系列前言一、如何实现&#xff1f;1、继承HwndHost2、添加Content属性3、创建wpf窗口并设置Content4、关闭wpf窗口 二、完整…

Flutter 常用插件Plugin整理并附带实例

最近有点空闲时间&#xff0c;正好写一篇文章&#xff0c;整理一下我们在Flutter开发中常用的插件Plugin使用并附带上实例。 在日常开发中&#xff0c;整个demo目前应该满足大家所有的开发需求&#xff0c;例如&#xff1a;http请求、列表刷新及加载、列表分组、轮播图、视频播…

ASP.Net添加Swagger注释

文章目录 Swagger添加Swagger注释 Swagger 添加Swagger注释 1、右击项目->选择属性->点击生成->输出&#xff0c;选中文档文件 2、配置服务 在program.cs 文件里配置SwaggerUI //增加项一 builder.Services.AddSwaggerGen(c> {c.SwaggerDoc("v1", ne…

新能源汽车充电桩主板的常见故障及解决办法

电桩主板作为充电桩的核心组件&#xff0c;直接影响着充电桩运行的安全性与稳定性。然而&#xff0c;在使用过程中&#xff0c;充电桩主板会因多种原因而出现一些故障情况&#xff0c;了解这些原因并采取相应的应对方法对维护充电桩的正常运行起着至关重要的作用。接下来&#…

【自我提升】一、Hyperledger Fabric 概念梳理

写在前面&#xff1a;最近因为业务需要&#xff0c;开始学习Hyperledger Fabric了&#xff0c;做java全栈工程师可真难搞。现在算是啥类型的都在涉及了&#xff0c;现在这个技术啥都不懂&#xff0c;就先开个学习专栏&#xff0c;记录记录。顺带也给各位道友参考参考。 目录 …

文献阅读工具-->Adobe pdf + 有道词典

Adobe pdf 有道词典 最近一直在考虑用什么文献阅读工具&#xff0c;痛点无非就是想用翻译功能&#xff0c;Adobe pdf的添加注释已经很好用了&#xff0c;使用了zotero&#xff0c;感觉不行&#xff08;不能直接对原文件修改&#xff0c;有副本&#xff0c;麻烦&#xff09;。…

vue + LogicFlow 实现流程图展示

vue LogicFlow 实现流程图展示 1.背景 部门主要负责低代码平台&#xff0c;配置端负责配置流程图&#xff0c;引擎端负责流程执行&#xff0c;原引擎端只负责流程执行控制以及流程历史列表展示。现在提出个新的要求&#xff0c;认为仅历史记录不直观&#xff0c;需要在展示完…

Unity学习日记 11.单词识别游戏

目录 1.返回鼠标单击对象的名字 2.鼠标拖动移动对象 3.实现鼠标跟随 4.场景准备工作 5.判断图片与框配对 6.根据配对结果放置图片 1.返回鼠标单击对象的名字 步骤&#xff1a; 创建一个ShowName的脚本&#xff0c;并挂载在摄像机上 RaycastHit2D hitInfo;void Update(){…

Tensorflow2.0笔记 - 使用compile,fit,evaluate,predict简化流程

本笔记主要用compile, fit, evalutate和predict来简化整体代码&#xff0c;使用这些高层API可以减少很多重复代码。具体内容请自行百度&#xff0c;本笔记基于FashionMnist的训练笔记&#xff0c;原始笔记如下&#xff1a; Tensorflow2.0笔记 - FashionMnist数据集训练-CSDN博…

【旅游景点项目日记 | 第一篇】项目服务架构、数据库表设计

Gitee仓库地址&#xff1a;travel-server&#xff1a;景点旅游项目服务端 文章目录 1.项目服务架构2.数据库设计2.1用户服务—travel_ums2.1.1 ums_user—用户表 2.2景点服务—travel_ams2.2.1 ams_attraction—景点表1.2.2 ams_resource_type—资源类型表 2.3票务服务—trabel…

前端框架的简单介绍

html html-结构 盖房子之前先划三室二厅 &#xff08;超文本标记语言&#xff09;(可以实现一切的文本) css css-样式 在房里添家具 &#xff08;层叠样式单&#xff09;(化妆在脸上叠加) javascript(js) javascript(js)-交互(行为) 我点击你打开 供显示信息的元…

持续集成与版本控制的相关概念

目录 一、持续集成 1.1 持续集成基本概念 1.1.1 持续集成的含义 1.1.1.1 持续集成流程是依赖产品版本迭代和版本分支而产生的 1.1.1.2 持续集成流程中包含的内容 1.1.2 传统打包模式说明 1.1.2.1 传统打包模式概述 1.1.2.2 传统打包模式问题 1.1.3 持续集成模式 1.1.…

GIt的原理和使用(五)

目录 多人协作 多人协作一 准备工作 协作开发 多人协作二 准备工作 额外场景 申请单合并分支 更推荐写法 远程分支删除后&#xff0c;本地git branch -a依然能看到的解决办法 多人协作 多人协作一 目标&#xff1a;在远程master分支下的file.txt文件新增代码“aaa”…