[JavaScript / leetcode] 56. 合并区间

95 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情

每日刷题 2022.10.22

题目

  • 以数组 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] 可被视为重叠区间。

解题思路

  • 合并区间数组,区间数组按照数组元素的区间左值进行排序,使区间相邻,只要按顺序遍历判断相邻区间是否可以合并即可。
  • 区间合并有24种情况,2类是可以合并和不能合并,4种情况是:首元素不能合并,交叉区间可以合并,包含区间可以合并,不交叉区间不能合并。
  • 首先判断最简单条件情况,数组长度为01时,直接返回原数组即可。
  • 对元素组进行排序,使用Arrays工具sort方法,比较器使用Comparator接口,其默认实现方法comparingInt可以将待排序元素转换为整数进行比较,使用lambda表达式将元素转换为整数。
  • 遍历数组按顺序处理每一个元素,每个元素的处理按照4种情况添加到结果数组中,使用addToMerge处理,返回当前结构数组的尾部元素下一个下标。
  • 结果数组中包含多余的值,使用Arrays工具的copyOfRange方法截取0index之间的数组返回即可。

代码

/**
 * @param {number[][]} intervals
 * @return {number[][]}
 */
var merge = function(intervals) {
  intervals.sort((a, b) => a[0] - b[0]);
  // console.log('排序',intervals);
  // 再处理合并
  // 保存最终的输出结果的数组
  let stack = [];
  // 记录栈顶的元素
  let tempt = [];
  // 中间变量
  let ch = [];
  // 模拟栈
  // 栈空放 一个数和栈顶的比,需要合并,合并后放入,不需要合并,直接放入
  for (let i = 0; i < intervals.length; i++) {
    if (stack.length == 0) {
      // 压入一个数
      stack.push(intervals[i]);
      // console.log('栈空',stack);
    }else {
      // 栈不为空,取栈顶元素和当前元素进行比较
      tempt = stack.pop();
      // console.log('tempt',tempt[1],'inter',intervals[i][0]);
      if (tempt[1] >= intervals[i][0]) {
        // 需要合并,取第一个的start 和 第二个的end
        // console.log('大于等于');
        ch.push(tempt[0]);
        tempt[1] > intervals[i][1] ? ch.push(tempt[1]) : ch.push(intervals[i][1]);
        // ch.push(intervals[i][1]);
        // 将新组成的push进去
        stack.push(ch);
        // 临时存储的数组置空
        ch = [];
      }else {
        stack.push(tempt);
        // 不需要合并
        stack.push(intervals[i]);
      }
      // console.log('stack',stack);
    }
  }
  return stack;
};