欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-08 14:27:29
...

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

题目:

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

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

示例:

  1. 示例1:
输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]
  1. 示例2:
输入: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左右两侧的区间:
  intervals: ...[1,3],[6,9]...
  newInterval: [4,5]
  3<4  && 5<6
  1. 合并,与newInterval存在交集的区间
  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记录合并的边界

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

/**
 * @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
};

博客: 前端小书童

每天的每日一题,写的题解会同步更新到公众号一天一大 lee 栏目
欢迎关注留言

公众号:前端小书童