【LeetCode每日一题】56. 合并区间

每日一题

2025.8.20

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

总体思路

按起点升序(若起点相同则按终点升序)对区间排序。

这样做后,所有可能与某区间重叠的区间都会紧跟在它后面出现,便于线性扫描合并。

用一个变量 current 表示正在合并中的区间(初始化为排序后第一个)。

从左到右依次遍历后续区间 iv:

  • 若 iv.start <= current.end,说明重叠/相邻(如 [1,4] 与 [4,5] 也要合并),更新:
    current.end = max(current.end, iv.end)
  • 否则,说明没有重叠:把 current 推入结果数组,然后把 iv 设为新的 current。

扫描结束后,把最后一个 current 推入结果,完成合并。

时间复杂度:排序 O(n log n),扫描 O(n),总 O(n log n)

空间复杂度:结果需要 O(k)(k 为合并后区间数);除结果外只用到常数级额外空间。

代码

golang

go 复制代码
// merge 合并所有重叠(或相邻)的区间。
// 输入输出均为 [][]int,其中每个区间为 [start, end]。
func merge(intervals [][]int) [][]int {
	// 1) 特判:空输入或只有一个区间,直接返回
	if len(intervals) <= 1 {
		return intervals
	}

	// 2) 按起点升序排序;若起点相等,按终点升序
	// sort.Slice 使用匿名比较函数,i、j 是索引,返回 true 表示 i 应排在 j 前面
	sort.Slice(intervals, func(i, j int) bool {
		if intervals[i][0] == intervals[j][0] {
			return intervals[i][1] < intervals[j][1]
            // 如果起点一样,就比较终点
		}
        // 否则,谁的起点小谁排前
		return intervals[i][0] < intervals[j][0]
	})

	// 3) 准备结果切片。预分配容量可小优化:最多就是 n 个
	res := make([][]int, 0, len(intervals))

	// 4) current 表示当前正在合并的区间(直接引用排序后的第一个)
	current := intervals[0]   //(current[0],current[1])当前正在合并的区间

	// 5) 线性扫描其余区间
	for i := 1; i < len(intervals); i++ {
		iv := intervals[i]

		// 判断是否重叠/相邻:只要下一个区间的起点 <= 当前区间的终点
		if iv[0] <= current[1] {
			// 可以合并:更新 current 的右端点为更大的那个
			if iv[1] > current[1] {
				current[1] = iv[1]
			}
			// 注意:不立即放入 res,继续尝试与后面的区间合并
		} else {
			// 不重叠:把当前合并结果推入 res,并开始新的 current
			//current := intervals[0] // 当前正在合并的区间
            //iv := intervals[i]      // 循环里取出来的一个新区间
			res = append(res, current)
			current = iv
		}
	}

	// 6) 别忘了把最后一个合并完成的区间放进去
	res = append(res, current)

	return res
}
go 复制代码
//无注释代码纯享
func merge(intervals [][]int) [][]int {
    if len(intervals) <= 1 {
        return intervals
    }
    sort.Slice(intervals,func(i, j int) bool {
        if intervals[i][0] == intervals[j][0] {
            return intervals[i][1] < intervals[j][1]
        }
        return intervals[i][0] < intervals[j][0]
    })
    res := make([][]int, 0, len(intervals))
    current := intervals[0]
    for i:=0; i<len(intervals); i++ {
        iv := intervals[i]
        if iv[0] <= current[1] {
            if iv[1] > current[1] {
                current[1] = iv[1]
            }
        }else{
            res = append(res,current)
            current = iv
        }
    }
    res = append(res, current)
    return res
}

golang知识

  • sort.Slice 是什么?

Go 标准库里有个 sort 包,可以帮我们对切片(slice)进行排序。

它的常用函数有:

sort.Ints([]int) ------ 排序一维整型切片

sort.Strings([]string) ------ 排序字符串切片

sort.Slice(slice, lessFunc) ------ 最通用的,用来自定义规则排序任意切片。

  • sort.Slice 的用法

它的函数签名大概是:

go 复制代码
func Slice(slice interface{}, less func(i, j int) bool)

第一个参数:你要排序的切片(任何类型的都可以)

第二个参数:一个比较函数,形式是 func(i, j int) bool

i、j 是切片里的索引

返回值 true 表示:切片的第 i 个元素应该排在第 j 个元素前面

make([][]int, 0, len(intervals)) 的三个参数

make(类型, 长度, 容量)

类型:[][]int

表示"切片的元素是 []int(区间),所以它是区间的列表"。

举例:[[1,3],[2,6]] 就是 [][]int。

长度:0

说明一开始里面没有任何元素(空切片)。

容量:len(intervals)

这里表示"预留容量 = 区间总数"。

因为最多结果里不会超过输入的数量(比如 4 个区间,合并后最多还是 4 个,不会更多)。

这样预先分配好空间,可以避免 append 时底层数组频繁扩容,稍微提高效率。

相关推荐
hweiyu001 天前
C++设计模式,高级开发,算法原理实战,系统设计与实战(视频教程)
c++·算法·设计模式
大千AI助手1 天前
粒子群优化(PSO)算法详解:从鸟群行为到强大优化工具
人工智能·算法·优化算法·pso·粒子群优化
我叫汪枫1 天前
C语言深度入门系列:第十一篇 - 动态内存管理与数据结构:程序世界的高效算法大师
c语言·数据结构·算法
Li_7695321 天前
优选算法100 题 ——1 双指针
算法
77qqqiqi1 天前
算法——数学基础
算法
啊?啊?1 天前
7 排序算法通关指南:从 O (n²)(选择 / 冒泡)到 O (nlogn)(快排 / 归并)+ 计数排序
数据结构·算法·排序算法
张较瘦_1 天前
[论文阅读] 算法 | 抗量子+紧凑!SM3-OTS:基于国产哈希算法的一次签名新方案
论文阅读·算法·哈希算法
芒克芒克1 天前
LeetCode 面试经典 150 题:多数元素(摩尔投票法详解 + 多解法对比)
算法·leetcode·面试
wow_DG1 天前
【Vue2 ✨】Vue2 入门之旅 · 进阶篇(二):虚拟 DOM 与 Diff 算法
开发语言·javascript·vue.js·算法·前端框架
和光同尘 、Y_____1 天前
BRepMesh_IncrementalMesh 重构生效问题
c++·算法·图形渲染