【LeetCode】56. 合并区间

leetcode

 

解题思路

  1. ​​排序预处理​​
    将区间按起始点升序排序,确保后续只需比较相邻区间即可完成合并。

  2. ​​贪心合并策略​​
    维护一个合并后的结果数组,逐个判断当前区间是否与结果数组最后一个区间重叠:

    • ​​重叠​​:更新结果数组最后一个区间的右边界为两者的最大值
    • ​​不重叠​​:将当前区间加入结果数组
       
  3. ​​边界处理​​

    • 空输入直接返回空数组
    • 初始化结果数组时直接放入第一个区间
       

复杂度分析

  • ​​时间复杂度​​:O(n log n),排序耗时 O(n log n),遍历合并耗时 O(n)
     
  • ​​空间复杂度​​:O(n),存储合并后的结果数组

代码实现

func merge(intervals [][]int) [][]int {
    // 1. 按区间起始点排序
    sort.Slice(intervals, func(i, j int) bool {
        return intervals[i][0] < intervals[j][0]
    })

    // 2. 初始化结果数组
    merged := [][]int{intervals[0]}

    // 3. 遍历合并结果区间
    for i := 1; i < len(intervals); i++ {
        last := merged[len(merged)-1]
        current := intervals[i]
        if current[0] <= last[1] { // 存在重叠
            if current[1] > last[1] { // 更新右边界为较大值
                merged[len(merged)-1][1] = current[1]
            }
        } else {
            merged = append(merged, current)
        }
    }

    return merged
}

运行示例

func main() {
    // 示例1:基本重叠
    intervals1 := [][]int{{1, 3}, {2, 6}, {8, 10}, {15, 18}}
    fmt.Println("示例1:", merge(intervals1)) // [[1 6] [8 10] [15 18]]

    // 示例2:端点重叠
    intervals2 := [][]int{{1, 4}, {4, 5}}
    fmt.Println("示例2:", merge(intervals2)) // [[1 5]]

    // 测试全包含场景
    intervals3 := [][]int{{1, 4}, {2, 3}} 
    fmt.Println("全包含:", merge(intervals3)) // [[1 4]]

    // 测试单元素输入
    intervals4 := [][]int{{5, 7}}
    fmt.Println("单元素:", merge(intervals4)) // [[5 7]]
}
示例1: [[1 6] [8 10] [15 18]]
示例2: [[1 5]]
全包含: [[1 4]]
单元素: [[5 7]]

扩展讨论

  • ​​端点重叠处理​​:示例2中的 [1,4] 和 [4,5] 属于端点相接的特殊重叠场景,算法已天然支持这种判断
     
  • ​​全包含优化​​:当 [1,4] 包含 [2,3] 时,算法自动保留更大的右边界
     
  • ​​时间复杂度优势​​:相比暴力法的 O(n²) 复杂度,排序后的贪心策略效率显著提升
posted @ 2025-05-28 11:37  云隙之间  阅读(30)  评论(0)    收藏  举报