【算法-LeetCode】56. 合并区间(数组;排序)

56. 合并区间 - 力扣(LeetCode)

发布:2021年9月17日21:30:56

问题描述及示例

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-intervals
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

示例 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] 可被视为重叠区间。

提示:
1 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 104

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-intervals
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的题解

总体思路是先对 intervals 数组按其中每个元素的第一位(也就是 intervals[i][0])由小到大进行排序。用一个栈结构 result 存放结果。

然后将 intervals 数组中的第一个元素 firstInterval 弹出(其实由尾部弹出也可以,这里和之前的排序也可以相互照应着思考),同时也取出 result 的栈顶元素 top(注意,firstIntervaltop 都是一个表示区间的二元数组),并判断这两个区间是否能够合并为一个区间:

  • 如果能,则合并为一个区间并压入 result 栈;
  • 如果不能,则直接分别将这两个区间压入result 栈。重复这个过程,直到 intervals 数组中没有元素。

详细解释请看下方注释:

/**
 * @param {number[][]} intervals
 * @return {number[][]}
 */
var merge = function(intervals) {
  // 先对intervals数组按照intervals[i][0]的大小排序,注意,sort函数会对原数组产生影响
  intervals.sort((a, b) => {
    return a[0] - b[0];
  });
  // result是一个栈结构,用于存储最终结果,其初始元素即为intervals的第一个元素
  // 注意,shift函数也会改变原数组
  let result = [intervals.shift()];
  // 当intervals数组不为空时
  while(intervals.length) {
    // 用shift函数获取intervals的第一个元素firstInterval,同时intervals数组长度也改变了
    let firstInterval = intervals.shift();
    // 用pop函数获取result的栈顶元素top,同时result数组长度也改变了
    let top = result.pop();
    // 如果top区间的上限大于等于firstInterval区间的下限,说明两个区间有重叠部分,需合并
    if(top[1] >= firstInterval[0]) {
      // 将两个区间合并为一个新区间,该新区间的下限即为top的下限,
      // 而新区间的上限则是top和firstInterval两个区间的上限的较大值
      result.push([top[0], Math.max(firstInterval[1], top[1])]);
    } else {
      // 否则,则说明两个区间没有重叠部分,不能合并,直接将两个区间先后压入result
      // 注意,这里一定得先压入top区间,然后再压入firstInterval区间
      result.push(top, firstInterval);
    }
  }
  // intervals数组为空时说明能合并的区间都合并完了,直接返回result
  return result;
};


提交记录
执行结果:通过
168 / 168 个通过测试用例
执行用时:76 ms, 在所有 JavaScript 提交中击败了88.97%的用户
内存消耗:39.7 MB, 在所有 JavaScript 提交中击败了45.57%的用户
时间:2021/09/17 21:33	

在性能方面,这个的算法的不足应该也就是 sort() 函数排序的性能的不足了,如果不使用原生API的话,应该有更好的排序实现方法,这里暂且按下不表。

其他的不足,应该就是这个程序对传入的参数做了修改,我一直觉得这样不大好,但是感觉也没必要特意搞个啥变量对原始数据进行拷贝,em……一时间也找不出更好的解决办法,暂且先这样吧。

官方题解

更新:2021年7月29日18:43:21

因为我考虑到著作权归属问题,所以【官方题解】部分我不再粘贴具体的代码了,可到下方的链接中查看。

更新:2021年9月17日21:34:27

参考:合并区间 - 合并区间 - 力扣(LeetCode)

【更新结束】

有关参考

更新:2021年9月17日21:35:26
参考:Array.prototype.pop() - JavaScript | MDN
参考:Array.prototype.shift() - JavaScript | MDN
参考:Array.prototype.sort() - JavaScript | MDN

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值