56. 合并区间

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

📝 核心笔记:合并区间 (排序 + 贪心)

1. 核心思想 (一句话总结)

"先排序,再接龙"。

只要按照左端点排序,重叠的区间就一定会挨在一起。我们只需要看当前区间能不能"接"上结果集里的最后一个区间。

2. 算法流程 (三步走)
  1. 排序 (Sort): 必须按照 左端点 (start) 从小到大排序。
  2. 判断 (Check):
    • 如果 当前左端点 p[0]****<=结果集最后一个右端点 last[1]->撞车了/重叠了。
    • 否则 ->没重叠,直接加入新区间。
  1. 合并 (Merge):
    • 发生重叠时,不要直接把当前区间的右端点赋给上一个。
    • 关键点: 要取最大值 Math.max(last[1], p[1])。因为可能存在"大包小"的情况(如 [1, 10] 和 [2, 3],合并后还是 [1, 10])。

🔍 代码回忆清单 (带注释版)

复制代码
// 题目:LC 56. 合并区间
class Solution {
    public int[][] merge(int[][] intervals) {
        // 关键点1:必须排序!按左端点升序
        // lambda 写法:(a, b) -> a[0] - b[0]
        Arrays.sort(intervals, (p, q) -> p[0] - q[0]); 

        List<int[]> ans = new ArrayList<>();
        
        for (int[] p : intervals) {
            int m = ans.size();
            // 关键点2:判断是否重叠
            // 必须 ans 不为空,且 当前左 <= 上一个右
            if (m > 0 && p[0] <= ans.get(m - 1)[1]) { 
                // 关键点3:合并动作
                // 吞并!更新右边界为两者的最大值 (千万别忘了 Math.max)
                ans.get(m - 1)[1] = Math.max(ans.get(m - 1)[1], p[1]); 
            } else {
                // 不重叠,另起炉灶
                ans.add(p); 
            }
        }
        // 关键点4:List 转 二维数组的标准写法
        return ans.toArray(new int[ans.size()][]);
    }
}

场景一:接龙(延长)------ 这是你直觉想到的情况

假设前一个区间是 [1, 5],当前区间是 [2, 8]。

  • 前一个 (ans.get(m-1)): [1, ----- 5]
  • 当前 (p): [2, -------- 8]
  • 合并结果 :应该变成 [1, 8]。

在这种情况下,p[1] (8) 确实比 ans.get(m-1)[1] (5) 大。 Math.max(5, 8) 选了 8 。这是符合直觉的:区间变长了。


场景二:包含(大包小)------ 这是必须要 Math.max 的原因!

假设前一个区间是 [1, 10],当前区间是 [2, 6]。 (注意:因为我们按左端点排序了,所以 [2, 6] 肯定排在 [1, 10] 后面处理)。

  • 前一个 (ans.get(m-1)): [1, ---------------- 10]
  • 当前 (p): [2, ---- 6]
  • 合并结果 :应该保持 [1, 10]。

如果你不用 Max,直接赋值 ans.get(m-1)[1] = p[1]: 结果就会变成 [1, 6]。 后果: 你把原本 6 到 10 这一段合法的范围给丢掉了!❌

使用 Max 的逻辑: Math.max(10, 6) 选了 10 。 这样才能保证:原本覆盖的范围,绝对不会因为合并了一个小区间而变短。


⚡ 快速复习 CheckList (易错点)

  • 忘了排序? 不排序这道题做不出来,必须按 start 排序。
  • 合并逻辑错? 是 Math.max,不是直接赋值!
    • 反例:[1, 5] 和 [2, 3]。如果不取 max,直接赋值变成 [1, 3] 就错了,应该是 [1, 5]。
  • 返回值写法? Java 中 List 转二维数组比较啰嗦:list.toArray(new int[list.size()][])。

🖼️ 场景联想

想象你在安排会议室:

  1. 先把所有预定单按开始时间排好序。
  2. 你拿着第一张单子 9:00 - 10:00 贴在门上。
  3. 第二张单子 9:30 - 11:00 来了。
  4. 一看 9:30 在 10:00 之前(重叠了),于是你把门上的单子改成 9:00 - 11:00(取结束时间晚的那个)。
  5. 第三张单子 12:00 - 13:00 来了。
  6. 12:00 在 11:00 之后(没重叠),你在门上贴第二张单子。
相关推荐
猿究院_夏燊2 小时前
Spring Bean 生命周期
java·后端·spring
Wang's Blog2 小时前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
inrichtt3 小时前
第八课时:SPI总线揭秘:四线全双工通信的奥
c语言·数据结构·stm32·单片机·嵌入式硬件
信誓旦旦的程序猿3 小时前
【Python量化实战宝典 #08】可转债与债券接口手册:转股价·溢价率·纯债价值(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
救救孩子把3 小时前
AI面试八股文-21_21-多模态Agent面试题-Vision-Language-Agent
人工智能·面试·职场和发展·llava·多模态agent
砚底藏山河3 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
Jlzn88883 小时前
华东电芯分选通道数怎么配才不堵线
java·人工智能·架构·自动化·制造
HPtiger3 小时前
数据结构——选择排序
数据结构·算法·排序算法
康实训3 小时前
老年评估仿真实训平台架构设计与老年人能力评估实训室教学落地实践
大数据·人工智能·算法·实训室·实训室建设
香吧香3 小时前
GRPC连接机制---长连接分析
java·网络与传输协议