leetCode-hot100-数组专题之区间问题

数组专题之区间问题

    • 知识点:
    • 解决思路:
    • 例题
      • 56.合并区间
      • 57.插入区间
      • 253.会议室 Ⅱ
      • 485.无重叠区间

数组区间问题是算法中常见的一类问题,它们通常涉及对数组中的区间进行排序、合并、插入或删除操作。无论是合并区间、插入区间还是删除重复空间,首先都需要区分需要处理的区间的条件,主要是对区间左右边界的比较。以下是数组区间问题的知识点和解决思路的总结:

知识点:

  1. 区间表示:一个区间通常用两个数表示,第一个数是区间的起始点,第二个数是区间的结束点。
  2. 区间排序:如果区间的起始点不同,可以通过排序快速找到重叠的区间,在例题中使用了Arrays.sort(),自定义比较器:
//按照数组区间的第一个元素排序
Arrays.sort(intervals,(a,b) -> a[0] - b[0]);
//按照数组区间的第二个元素排序
Arrays.sort(intervals,(a,b) -> a[1]- b[1]);
  1. 合并区间:当两个区间的起始点不同,但一个区间的结束点大于或等于另一个区间的起始点时,这两个区间可以合并为一个区间。
  2. 插入区间:当需要将一个新的区间插入到已有的区间集合中时,需要考虑新区间与已有区间的关系,可能需要合并区间或调整区间顺序。
  3. 无重叠区间:当区间之间没有公共部分时,这些区间是无重叠的。

解决思路:

  1. 排序:对于区间问题,通常首先需要对区间进行排序,以便于后续操作。排序可以按照起始点进行,也可以按照结束点进行。
  2. 合并区间:(56)
    • 遍历排序后的区间,检查当前区间是否可以与前一个区间合并。
    • 如果可以合并,更新合并后的区间的起始点和结束点。
    • 继续遍历,直到处理完所有区间。
  3. 插入区间:(57)
    • 遍历排序后的区间,找到插入位置。
    • 如果新区间与当前区间重叠,需要合并区间。
    • 更新插入后的区间顺序。
    • 继续遍历,直到处理完所有区间。
  4. 无重叠区间:(253、485)
    • 遍历排序后的区间,检查当前区间是否与前一个区间重叠。
    • 不重叠的条件是后一个区间的左边界大于等于前一个区间的右边界
      在解决区间问题时,通常需要考虑区间的特殊性质,比如区间的大小、起始点和结束点等。此外,还需要注意边界条件,比如空区间、只有一个区间的情况等。通过以上知识点和解决思路,可以解决大多数基本的区间问题。

例题

56.合并区间

思路
本题使用扫描线法来解决,首先要对二维数组进行排序,根据其中数组元素的第一个数字进行升序排列(这里代码里用了一种正则表达式的排序方法,会在知识点总结进行介绍),在排序完成之后进行扫描,有三种情况,我们将最前面的数组区间设置为[start,end],向后扫描:

  1. 后面的区间的starti大于end,那么直接将前一个区间加入结果集中

  2. 后面的区间的starti小于end,这里又会分出两种情况:

    (1)后面的区间完全包含在前面的区间
    (2)后面的区间的endi大于前面区间的end
    以上两种情况我们都需要将end更新为最大的end值,所以可以归结为一类

如果还是不太理解的话可以点击视频讲解-合并区间。
时间复杂度
首先将区间按照起始时间排序,这需要O(nlogn)的时间复杂度,然后遍历排序后的区间,维护一个当前区间的起始时间和结束时间。如果遇到与当前区间重叠的新区间,就更新当前区间的结束时间。如果遇到与当前区间不重叠的新区间,就把当前区间加入到结果列表中,然后更新当前区间的起始时间和结束时间,这个遍历过程需要O(n)的时间复杂度。所以总的时间复杂度是O(nlogn) + O(n) = O(nlogn)
代码实现

class Solution {public int[][] merge(int[][] intervals) {//将ntervals按照数组元素的第一个数排序Arrays.sort(intervals,(a,b) -> a[0] - b[0]);List<int[]> ans = new ArrayList<>();int start = intervals[0][0];int end = intervals[0][1];for(int[] interval : intervals){if(interval[0] > end){ans.add(new int[]{start,end});start = interval[0];end = interval[1];}else{end = Math.max(end,interval[1]);}}ans.add(new int[]{start,end});return ans.toArray(new int[ans.size()][]);}
}

知识总结
1.List的常见使用

//向List中添加元素
List.add(e)
//根据索引获取元素
List.get(index)
//按照索引删除
List.remove(index)
//按照元素内容删除
List.remove(Object o)
//判断List中是否包含某个元素,返回true或false
List.contains(Object o)
//使用element替换该索引处的值
List.set(index,element)
//在该索引位置插入一个值
List.add(index,element)
//返回该值的第一个索引
List.indexOf(Object o)
//返回该值的最后一个索引
List.lastIndexOf(Object o)
//截取List的部分元素,
//注意这里时左闭右开,即fromIndex的值要包括,但是toIndex的值不包括,索引从0开始
List.subList(fromIndex, toIndex)
//返回该List中的元素数
List.size()
//对比两个List的所有元素是否相同
//两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象
List1.equals(List2)
//判断List是否为空
List.isEmpty()
//返回Iterator集合对象
List.iterator()
//将List转换为字符串
List.toString()
//将List转换为数组
List.toArray()

2.二维数组的排序

Arrays.sort(intervals,(a,b) -> a[0] - b[0]);

intervals是一个二维数组,每个元素都是一个包含两个整数的数组,表示一个时间区间的开始和结束时间。(a, b) -> a[0] - b[0]是一个lambda表达式,用作排序的比较函数。它比较两个数组ab的第一个元素,如果a[0]小于b[0],则返回一个负数,表示a应该排在b前面。经过排序,intervals数组中的时间区间会按照开始时间的升序排列。
为什么不能直接使用Arrays.sort(intervals)呢?
由于 intervals 数组中的元素是 int[] 类型的数组。在这种情况下,直接使用 Arrays.sort(intervals) 是不正确的,因为 Java 默认使用数组元素的比较顺序进行排序,对于 int[] 类型来说,比较的是数组的引用,而不是数组中的元素。
对于一维数组,比如 int[] 类型,Arrays.sort() 方法可以直接使用,它会按照数组元素的自然顺序进行排序。
但是对于二维数组 int[][] 类型,情况就不太一样了。因为二维数组的元素是一维数组,所以 Arrays.sort() 默认是按照一维数组的引用进行排序的,而不是按照一维数组中的元素进行排序。
为了按照二维数组中的特定元素进行排序,需要提供一个自定义的比较器,例如 (a, b) -> a[0] - b[0] ,这样可以告诉 Arrays.sort() 方法按照二维数组中的第一个元素进行排序。

57.插入区间

思路:
根据题目要求可以将数组intervals分为三部分,第一部分为需要合并区间的左边部分,可以直接加入结果数组中,第二部分是需要和插入区间合并的区间,第三部分是合并后右侧剩下的区间,直接加入结果数组,区分每个部分的条件如下:
(1)左侧部分:所有数组元素的右边界应该小于插入元素的左边界(intervals[i][1] < newInterval[0]
(2)合并部分:所有数组元素的左边界应该小于插入元素的右边界(intervals[i][0] <= newInterval[1]
下面是一个简单画图说明;
在这里插入图片描述

时间复杂度:
这段代码的时间复杂度为O(n),其中nintervals数组的长度。
代码实现:

class Solution {public int[][] insert(int[][] intervals, int[] newInterval) {List<int[]> ans  = new ArrayList<>();int n = intervals.length;int i = 0;//加入合并区间左边部分的元素while(i < n && intervals[i][1] < newInterval[0]){ans.add(intervals[i++]);}//合并区间if(i < n){newInterval[0] = Math.min(intervals[i][0],newInterval[0]);while(i < n && intervals[i][0] <= newInterval[1]){newInterval[1] = Math.max(intervals[i++][1],newInterval[1]);}}ans.add(newInterval);//处理剩下的元素,即合并区间右边的元素while(i < n){ans.add(intervals[i++]);}return ans.toArray(new int[ans.size() - 1][]);}
}

253.会议室 Ⅱ

思路:
本题采用优先队列解决,使用一个升序排列的优先队列记录每个会议的结束时间,然后遍历数组,当后一个会议的开始时间大于前一个会议的结束时间时,说明两个会议并不冲突,此时前一个会议从优先队列中弹出,后一个会议加入优先队列;反之,前一个会议不弹出,并将后一个会议加入优先队列,可以看出此时队列的大小即为需要会议室的数量,最后处理完所有的会议后返回优先队列的大小即可。
时间复杂度:
这段代码的时间复杂度为O(nlogn),其中nintervals的长度。这是因为使用了优先队列来存储会议的结束时间,并进行了排序。优先队列的插入和删除操作的时间复杂度为O(logn),而插入和删除操作都被执行了n次,所以总的时间复杂度为O(nlogn)
代码实现:

class Solution {public int[][] merge(int[][] intervals) {if(intervals.length == 0) return 0;//使用优先队列来存储会议的结束时间//创建了一个容量为intervals.length的优先队列,按照整数元素的升序排列PriorityQueue<Integer> ans = new PriorityQueue<>(intervals.length, (a , b) -> a - b);ans.offer(intervals[0][1]);for(int i = 1; i < intervals.length ;i++){//会议不冲突时将其弹出,会议冲突时将冲突会议加入//最终优先队列的大小即为需要会议室的数量if(intervals[i][0] >= ans.peek()){ans.poll();}ans.offer(intervals[i][1]);}return ans.size();}
}

485.无重叠区间

思路:
本题需要得到移除区间的最小数量,得到一个不重叠的区间,这里首先将每个区间按照右边界来排序,因为右边界越小说明后面区间可以选择空间越大,这样移除的区间就是最少的。判断不是重叠区间的条件是区间的左边界大于等于上一个区间的右边界。
时间复杂度:
这段代码的时间复杂度为O(nlogn),其中nintervals数组的长度。代码中的Arrays.sort()函数的时间复杂度为O(nlogn),排序完成后,遍历intervals数组的时间复杂度是O(n),因此总的时间复杂度为O(nlogn)
代码实现:

class Solution {public int eraseOverlapIntervals(int[][] intervals) {if(intervals.length < 2) return 0;//将数组按照右边升序排序Arrays.sort(intervals,(a,b) -> a[1]- b[1]);int cnt = 1;int end = intervals[0][1];//遍历数组,找到所有不重复的元素,条件是区间的左边界大于end//符合条件更新end值,并cnt+1for(int i = 1; i < intervals.length;i++){if(intervals[i][0] >= end){end = intervals[i][1];cnt++;}}//返回总数量减去不重叠区间的数量即为结果return intervals.length - cnt;}
}

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

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

相关文章

【HarmonyOS尝鲜课】- 下载、安装DevEco Studio以及配置环境、创建运行HarmonyOS项目

下载、安装开发工具 进入DevEco Studio下载官网&#xff0c;单击“立即下载”进入下载页面。 这里以Windows为例进行安装&#xff0c;可以根据操作系统选择对应的版本进行下载。 下载完成后解压一下&#xff0c;进入文件里&#xff0c;双击应用程序&#xff0c;打开安装向导&a…

Redis主从、哨兵、集群讲解

一、Redis主从 大家在面试中可能经常会被问到Redis的高可用问题。Redis高可用回答包括两个层面&#xff0c;一个就是数据不能丢失&#xff0c;或者说尽量减少丢失 ;另外一个就是保证Redis服务不中断 。 对于尽量减少数据丢失&#xff0c;可以通过AOF和RDB保证。 对于保证服务…

linux---线程控制

线程和进程 以前我们要同时跑多个程序&#xff0c;可以通过fork()多个子进程&#xff0c;然后通过系统函数进行程序的替换&#xff0c;但是创建进程代价大&#xff0c;不仅要拷贝一份父进程的地址空间&#xff0c;页表&#xff0c;文件表述符表等。但是线程不需要因为是进程的…

windows docker desktop 更换镜像存储目录

windows docker desktop 更换镜像存储目录 方法&#xff1a;如图&#xff0c;Browse浏览一个新的目录并选中&#xff0c;确定后&#xff0c;程序会开始stop&#xff0c;在stop完成前&#xff0c;会持续迁移原有镜像到新的位置&#xff0c;你会发现目标位置的磁盘占用空间越来越…

Mac网线连接windows本【局域网互传文件】

Mac网线连接windows本【局域网互传文件】 两台电脑网线互联 Mac->网络->USP TCP/IP 手动配置IP&#xff0c;子网掩码&#xff0c;路由器 windows 网络和Internet配置->更改适配器选项->以太网->Internet协议版本4&#xff08;TCP/IPv4&#xff09;->属性 …

K8S/ hpa分享

在 Kubernetes 中&#xff0c;HorizontalPodAutoscaler 自动更新工作负载资源 &#xff08;例如 Deployment 或者 StatefulSet&#xff09;&#xff0c; 目的是自动扩缩工作负载以满足需求。 hpa的使用本身还是很简单的 示例如下&#xff1a; 官网示例 apiVersion: apps/v1 k…

NetCore发布的时候怎么去除生成的多余的语言文件夹cs,de...,Microsoft.CodeAnalysis语言资源文件

1、问题&#xff1a; .NetCore 3.1 发布出来的publish目录一大堆杂七杂八的文件夹如下图&#xff1a; 2、产生原因 由Microsoft.VisualStudio.Web.CodeGeneration.Design包导致 3、解决方法&#xff1a; 如果确实需要某种语言资源文件&#xff0c;可以这样&#xff0c;右键编…

压摆率SR、增益带宽积GBP、开环增益Aol

运放的选型对运放电路的实际效果非常关键&#xff0c;一定要理解运放重要参数的概念。下面几天将对运放的选型进行系统学习并做实验 运放的压摆率&#xff08;Slew Rate&#xff0c;简称SR&#xff09;是指闭环放大器在输入为阶跃信号时&#xff0c;输出电压时间变化率的平均值…

vue打包部署到springboot,通过tomcat运行

tomcat默认端口 8080springboot端口 9132vue 端口 9131 框架 项目是基于SpringBootVue前后端分离的仓库管理系统 后端&#xff1a;SpringBoot MybatisPlus前端&#xff1a;Node.js Vue element-ui数据库&#xff1a;mysql 一. 打包Vue项目 cmd中输入命令 npm run build 后…

深度学习之基于YoloV5-Deepsort人物识别与追踪项目

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与目标 本项目旨在利用深度学习技术&#xff0c;结合YoloV5和Deepsort算法&#xff0c;开发一个高效、…

前端:音频可视化(H5+js版本)

一、效果展示 HTML5JS实现一个简单的音频可视化 二、代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>音频可视化</title><style></style></head><body><divs…

非平稳信号的傅里叶变换与短时傅里叶变换

一、仿真一个非平稳的时间序列。 N 10000; t 0:N-1; z1 4.2*sin(2*pi/20.*t5); z2 2.2*sin(2*pi/100.*(10.001*t).*t8); w1 randn(length(t),1); yz1z2w1; figure;plot(y,LineWidth,1.5);grid on; ylabel(Signal); xlabel(Time); 二、傅里叶变换&#xff08;FFT&#xff…

Llama 3超级课堂作业笔记

文章目录 基础作业完成 Llama 3 Web Demo 部署环境配置下载模型Web Demo 部署对话截图 使用 XTuner 完成小助手认知微调Web Demo 部署自我认知训练数据集准备训练模型推理验证 使用 LMDeploy 成功部署 Llama 3 模型环境&#xff0c;模型准备LMDeploy CLI chatLMDeploy模型量化(…

SQL Server 2022安装+SQL Server最新补丁+smss工具连接超详细教程

文章目录 一、SQL Server 2022安装二、SSMS的安装与连接三、最新补丁下载总结 一、SQL Server 2022安装 官网下载安装包&#xff1a;https://www.microsoft.com/en-us/sql-server/sql-server-downloads 打开 选择自定义 更改你要安装到的位置后进行安装 安装程序包下载完后会自…

将本地项目代码上传到别人GitHub的远程分支上流程记录

首先将别人的项目克隆到本地&#xff1a; git clone 项目地址 然后cd进项目中&#xff0c;查看分支名称&#xff1a; git branch git branch -a 切换分支&#xff1a; git checkout 远程分支名 &#xff08;必须与所要提交代码的远程分支同名&#xff09; 截图案例&#xff1…

简单的TCP网络程序:英译汉服务器

一、服务器的初始化 下面介绍程序中用到的socket API,这些函数都在sys/socket.h中。 1.创建套接字 socket()&#xff1a; ⭐参数介绍&#xff1a; socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符;应用程序可以像读写文件一样用read/write在网…

AI大模型日报#0523:中国大模型价格战的真相、大模型「上车」、王小川首款 AI 应用

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE 4.0&#xff09;、“零一万物”&#xff08;Yi-Large&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xf…

04. Redis 配置文件

文章目录 单位包含网络 NETWORK通用 GENERAL快照 SNAPSHOTTING主从复制 REPLICATION安全 SECURITY客户端 CLIENTS内存设置 MEMORY MANAGEMENTAPPEND ONLY MODE 模式&#xff08;aof 的配置&#xff09; 单位 配置文件对大小写不敏感&#xff08;unit单位&#xff09;。 包含 …

罗德与施瓦茨ZNB20矢量网络分析仪怎么读取Trace?

矢量网络分析仪(VNA)是电子测量领域广泛应用的重要仪器&#xff0c;可以帮助工程师精确测量各种射频和微波设备的参数&#xff0c;为设计优化、故障诊断等提供关键数据支持。作为业界领先的VNA制造商&#xff0c;罗德与施瓦茨的ZNB20型号在测量精度、动态范围、扫描速度等方面都…

家政预约小程序05服务管理

目录 1 设计数据源2 后台管理3 后端API4 调用API总结 家政预约小程序的核心是展示家政公司提供的各项服务的能力&#xff0c;比如房屋维护修缮&#xff0c;家电维修&#xff0c;育婴&#xff0c;日常保洁等。用户在选择家政服务的时候&#xff0c;价格&#xff0c;评价是影响用…