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

力扣第五十六题——合并区间

内容介绍

以数组 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

完整代码

 class Solution {public int[][] merge(int[][] intervals) {if (intervals.length == 0) {return new int[0][2];}Arrays.sort(intervals, new Comparator<int[]>() {public int compare(int[] interval1, int[] interval2) {return interval1[0] - interval2[0];}});List<int[]> merged = new ArrayList<int[]>();for (int i = 0; i < intervals.length; ++i) {int L = intervals[i][0], R = intervals[i][1];if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < L) {merged.add(new int[]{L, R});} else {merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], R);}}return merged.toArray(new int[merged.size()][]);}
}

思路详解

一、问题背景

给定一个二维数组intervals,其中每个子数组表示一个区间,我们需要合并这些区间,使得没有重叠的区间尽可能紧密相连。

二、解题思路

  1. 排序

    • 首先,我们需要对intervals数组进行排序。排序的依据是每个子数组的开头位置,因为合并的目的是让没有重叠的区间尽可能紧密相连。
  2. 合并区间

    • 创建一个List<int[]>,用于存储合并后的区间。
    • 遍历排序后的intervals数组,对于每个区间,如果当前列表为空或者当前区间的左端点大于列表中最后一个区间的右端点,则将当前区间添加到列表中。
    • 如果当前区间的左端点小于或等于列表中最后一个区间的右端点,则将列表中最后一个区间的右端点更新为当前区间右端点中的较大者。
  3. 返回结果

    • 遍历完成后,将List<int[]>转换为二维数组并返回。

三、代码详解

  1. 排序
    • 使用Arrays.sort方法对intervals数组进行排序,比较器比较的是每个子数组的第一个元素。
Arrays.sort(intervals, new Comparator<int[]>() {public int compare(int[] interval1, int[] interval2) {return interval1[0] - interval2[0];}
});
  1. 合并区间
    • 创建一个List<int[]>,用于存储合并后的区间。
    • 遍历排序后的intervals数组,对于每个区间,根据合并策略添加或更新列表中的区间。
List<int[]> merged = new ArrayList<int[]>();
for (int i = 0; i < intervals.length; ++i) {int L = intervals[i][0], R = intervals[i][1];if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < L) {merged.add(new int[]{L, R});} else {merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], R);}
}
  1. 返回结果
    • 遍历完成后,将List<int[]>转换为二维数组并返回。
return merged.toArray(new int[merged.size()][]);

四、总结

通过上述步骤,我们能够有效地合并区间,使得没有重叠的区间尽可能紧密相连。关键在于正确地排序区间并合并它们。这种方法的时间复杂度为O(n log n),其中n是intervals数组的长度,因为排序操作的时间复杂度为O(n log n)。空间复杂度为O(n),用于存储合并后的区间。

知识点精炼

一、核心概念

  1. 排序算法:在解决组合问题时,排序可以帮助我们找到最优解或近似解。
  2. 动态规划:在某些情况下,我们可以通过动态规划来优化算法,减少重复计算。
  3. 二维数组:在处理与位置相关的数据时,二维数组是一个非常有用的数据结构。

二、知识点精炼

  1. 区间合并问题

    • 给定一个二维数组intervals,其中每个子数组表示一个区间,需要合并这些区间,使得没有重叠的区间尽可能紧密相连。
  2. 排序

    • 使用Arrays.sort方法对intervals数组进行排序,比较器比较的是每个子数组的第一个元素。
  3. 合并区间

    • 遍历排序后的intervals数组,对于每个区间,根据合并策略添加或更新列表中的区间。
  4. 返回结果

    • 遍历完成后,将List<int[]>转换为二维数组并返回。

三、性能分析

  • 时间复杂度:O(n log n),其中n是intervals数组的长度,因为排序操作的时间复杂度为O(n log n)。
  • 空间复杂度:O(n),用于存储合并后的区间。

四、实际应用

  • 数据处理:在处理与位置相关的数据时,这种算法可以帮助我们合并区间,使得没有重叠的区间尽可能紧密相连。
  • 算法竞赛:在算法竞赛中,掌握这种算法对于解决与区间合并相关的问题非常有帮助。

五、代码实现要点

  • 排序:正确使用Arrays.sort方法进行排序。
  • 合并区间:正确实现合并策略,避免数组越界和重复添加。
  • 返回结果:正确返回合并后的区间数组。

 合并时如何避免重复

  1. 排序:首先对所有区间进行排序,确保每个区间的起始位置是唯一的。

  2. 迭代合并:遍历排序后的区间列表,对于每个区间,检查它是否与列表中的最后一个区间重叠或完全包含在最后一个区间内。如果是,则更新最后一个区间的结束位置;如果不是,则将当前区间添加到列表中。

  3. 去重:在添加新区间之前,检查它是否已经在列表中。如果是,则跳过它,避免重复添加。

  4. 返回结果:遍历完成后,将合并后的区间列表转换为二维数组并返回。

以下是代码实现:

class Solution {public int[][] merge(int[][] intervals) {if (intervals.length == 0) {return new int[0][2];}Arrays.sort(intervals, new Comparator<int[]>() {public int compare(int[] interval1, int[] interval2) {return interval1[0] - interval2[0];}});List<int[]> merged = new ArrayList<>();int[] last = intervals[0];merged.add(last);for (int i = 1; i < intervals.length; i++) {int[] current = intervals[i];if (current[0] <= last[1]) {// 如果当前区间与最后一个区间重叠,更新最后一个区间的结束位置last[1] = Math.max(last[1], current[1]);} else {// 如果当前区间与最后一个区间不重叠,添加当前区间merged.add(current);last = current;}}return merged.toArray(new int[merged.size()][]);}
}

在这个实现中,我们首先对区间进行排序,然后遍历排序后的区间列表。对于每个区间,我们检查它是否与列表中的最后一个区间重叠或包含在最后一个区间内。如果是,我们更新最后一个区间的结束位置;如果不是,我们将当前区间添加到列表中。这样,我们就能够确保不会重复添加区间,也不会将已经包含在当前合并区间内的区间再次添加。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 设计模式-装饰者模式
  • ubuntu创建txt
  • 2024年TI杯E题-三子棋游戏装置方案分享-jdk123团队-第二弹 手搓机械臂
  • 搅拌站智能化改造,数字化管理如何助力降本增效?
  • 走心解答hashCode与equals,尽量说明白
  • Windows图形界面(GUI)-MFC-C/C++ - 树形视图(Tree Control) - CTreeCtrl
  • 超声波眼镜清洗机哪个更好用?四款清洁力强的超声波清洗机推荐
  • 24.8.9.11数据结构|链栈和队列
  • 程序人生-Hello’s P2P
  • vue3引入模块报错:无法找到模块“xxx”的声明文件
  • Java 守护线程练习 (2024.8.12)
  • linux 下 QT5如何编译成32位或64的方法
  • 小白零基础学数学建模系列-Day3-线性回归模型的构建与评估
  • 基于STM32开发的智能农业环境监测系统
  • 看过来!数学建模国赛常见问题汇总
  • 【node学习】协程
  • 【RocksDB】TransactionDB源码分析
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Cookie 在前端中的实践
  • Java基本数据类型之Number
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 大型网站性能监测、分析与优化常见问题QA
  • 工程优化暨babel升级小记
  • 官方解决所有 npm 全局安装权限问题
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 使用Gradle第一次构建Java程序
  • 微服务核心架构梳理
  • 用Python写一份独特的元宵节祝福
  • 说说我为什么看好Spring Cloud Alibaba
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • (2)从源码角度聊聊Jetpack Navigator的工作流程
  • (30)数组元素和与数字和的绝对差
  • (Java企业 / 公司项目)点赞业务系统设计-批量查询点赞状态(二)
  • (poj1.2.1)1970(筛选法模拟)
  • (不用互三)AI绘画:科技赋能艺术的崭新时代
  • (二)换源+apt-get基础配置+搜狗拼音
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (回溯) LeetCode 40. 组合总和II
  • (南京观海微电子)——COF介绍
  • (三)elasticsearch 源码之启动流程分析
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (五)Python 垃圾回收机制
  • (一)SvelteKit教程:hello world
  • (一)为什么要选择C++
  • (转)linux 命令大全
  • (转)菜鸟学数据库(三)——存储过程
  • ***测试-HTTP方法
  • *算法训练(leetcode)第四十天 | 647. 回文子串、516. 最长回文子序列
  • .NET 8 编写 LiteDB vs SQLite 数据库 CRUD 接口性能测试(准备篇)
  • .net core 管理用户机密
  • .net mvc部分视图