【一天一大 lee】插入区间 (难度:困难) - Day20201104

2020-11-11 14:17:23 浏览数 (2)

题目:

给出一个无重叠的 ,按照区间起始端点排序的区间列表。

在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。

示例:

  1. 示例1:
代码语言:javascript复制
输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]
  1. 示例2:
代码语言:javascript复制
输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出:[[1,2],[3,10],[12,16]]
解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。

抛砖引玉

思路:

输出的结果有两种可能:

  1. 不合并,intervals中处在newInterval左右两侧的区间:
代码语言:javascript复制
  intervals: ...[1,3],[6,9]...
  newInterval: [4,5]
  3<4  && 5<6
  1. 合并,与newInterval存在交集的区间
代码语言:javascript复制
  intervals: ...[1,3], ... ,[6,9]...
  newInterval: [2,7]
  min(1,2)  max(9,7)

逻辑:

按照上面的思路:intervals中的区间可以分类三种:

  1. newInterval左侧区间
  2. 与newInterval存在交集的区间
  3. newInterval右侧区间

循环区间intervals,逐个向结果数组中推送子区间

  • 声明交集合并后的区间边界:left、right
  • 当遍历的区间与newInterval存在交集时使用left、right记录合并的边界

抛砖引玉

代码语言:javascript复制
/**
 * @param {number[][]} intervals
 * @param {number[]} newInterval
 * @return {number[][]}
 */
var insert = function(intervals, newInterval) {
let len = intervals.length, 
    _result = [],
    i = 0,
    rightChild = 0, // 右侧区间数量
    left = newInterval[0],  // 合并集合的边界
    right = newInterval[1]  // 合并集合的边界

  while(i < len){
    // newInterval 左侧区间
    if(intervals[i][1] < newInterval[0]){
     _result.push(intervals[i])
    }else if(intervals[i][0] > newInterval[1]){
      // newInterval 右侧区间 第一次遍历到右侧区间是添加合并后的区间
      if(rightChild === 0) _result.push([left, right]);
      _result.push(intervals[i]);
      rightChild  
    }else{
      // 存在交集区间
      left = Math.min(left, intervals[i][0]);
      right = Math.max(right, intervals[i][1]);
    }
    i  
  }
  // 如果不存在合右侧区间,即合并后的区间包括了intervals最后的子区间
  // 则须要最后追加合并区间到结果数组中
  if(rightChild === 0) _result.push([left, right]);
  return _result
};

0 人点赞