合并区间

73 阅读1分钟

 题目描述:以数组 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].

​编辑

思路

prev 初始为第一个区间,cur 表示当前的区间,res 表示结果数组

  • 开启遍历,尝试合并 prev 和 cur,合并后更新到 prev
  • 合并后的新区间还可能和后面的区间重合,继续尝试合并新的 cur,更新给 prev
  • 直到不能合并 —— prev[1] < cur[0],此时将 prev 区间推入 res 数组

合并的策略

  • 原则上要更新prev[0]和prev[1],即左右端:
  1. prev[0] = min(prev[0], cur[0])
  2. prev[1] = max(prev[1], cur[1])
  • 但如果先按区间的左端排升序,就能保证 prev[0] < cur[0]
  • 所以合并只需这条:prev[1] = max(prev[1], cur[1])

易错点

我们是先合并,遇到不重合再推入 prev。
当考察完最后一个区间,后面没区间了,遇不到不重合区间,最后的 prev 没推入 res。
要单独补上。

var merge = function (intervals) {
  let res = [];
  intervals.sort((a, b) => a[0] - b[0]);

  let prev = intervals[0];

  for (let i = 1; i < intervals.length; i++) {
    let cur = intervals[i];
    if (prev[1] >= cur[0]) { // 有重合
      prev[1] = Math.max(cur[1], prev[1])
    } else {       // 不重合,prev推入res数组 
      res.push(prev);
      prev = cur;  // 更新 prev
    }
  }

  res.push(prev);
  return res;
};