[路飞]_合并区间

497 阅读2分钟

56. 合并区间

题目: 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
这题意应该是比较好懂的一题了,但是往往很好理解的题,解题确花费不少时间
这里准备两种测试用例进行解释,


先解释一下这道题我觉得一种有意思的解法,也是我采用的解法
先循环一次,将itervals中每个二维数组的数都进行计数,那怎么记数法呢
就是将二维数组中的第一个数字计为1,第二个数字计为-1
那为什么这么做,接着往下看

intervals = [[1,3],[2,6],[8,10],[15,18]]

从上述数组中,记数过后 可以得到以下二维数组

arr = [[1,1],[3,-1],[2,1],[6,-1],[8,1],[10,-1],[15,1],[18,-1]]

如果我们进行第一个数进行排序可得

arr = [[1,1],[2,1],[3,-1],[6,-1],[8,1],[10,-1],[15,1],[18,-1]]

那通过循环arr,对二维数组进行第二个数的累加 是不是能得到以下结果

[1,1]->[2,1]->[3,-1]->[6,-1]->[8,1]->[10,-1],[15,1],[18,-1]
sum:1 -> 2 -> 1 -> 0 -> 1 -> 0 -> 1 -> 0

从结果来看找寻和为0的区间是不是为 [1,6],[8,10],[15,18] 那这就得到了题目想要的结果,呆木如下

var merge = function(intervals) {
    // 创建计数用的数组
    let arr = []
    // 设置每个元素初始值
    let temp = new Array(2)
    for(let [num1,num2] of intervals){
        temp[0] = num1
        temp[1] = 1
        //这里解构是因为引用类型的关系,如果不这样结构的话 bug会出现,可以亲手试试
        arr.push([...temp])
        temp[0] = num2
        temp[1] = -1
        arr.push([...temp])
    }
    //按第一个元素的大小进行排序
    arr.sort((a,b)=>a[0]-b[0])
    // pre 初始值设为第一个元素,sum 第一个元素的记数值,res为结果集
    let pre = arr[0][0] , sum = arr[0][1],res =[]
    for(let i = 1 ; i < arr.length; i++){
        if(pre === -1){
            pre = arr[i][0]
        }
        sum += arr[i][1]
        if(sum === 0){
            temp[0] = pre;
            temp[1] = arr[i][0]
            res.push([...temp])
            pre = -1
        }
    }
    return res
};

大家拿上述代码去跑测试用例会发现不能通过,因为还有一种特殊情况的用例还没有解决

intervals = [[1,4],[4,5]]

在这个用例中 记数出来的arr如下

arr = [[1,1],[4,-1],[4,1],[5,-1]]

这里会发现有两个下标元素一样的,但是记数不同,那么在上述代码中执行到统计sum的时候会出现错误, 通过调试,或者debug一下 会发现上述sort排序中还需处理一下

var merge = function(intervals) {
    // 创建计数用的数组
    let arr = []
    // 设置每个元素初始值
    let temp = new Array(2)
    for(let [num1,num2] of intervals){
        temp[0] = num1
        temp[1] = 1
        //这里解构是因为引用类型的关系,如果不这样结构的话 bug会出现,可以亲手试试
        arr.push([...temp])
        temp[0] = num2
        temp[1] = -1
        arr.push([...temp])
    }
    //进行排序
    arr.sort((a,b)=>{
        // 这里也可以写 a[0] -b[0] 因为只有===0的时候说false
        if(a[0]-b[0] !== 0){
            // 当第一个元素不相等时, 从小到大排序
            return a[0] - b[0]
        }else{
            // 相等时 ,比较第二个元素的大小,按从大到小的排序
            return b[1] - a[1]
        }
        
    })
    // pre 初始值设为第一个元素,sum 第一个元素的记数值,res为结果集
    let pre = arr[0][0] , sum = arr[0][1],res =[]
    for(let i = 1 ; i < arr.length; i++){
        if(pre === -1){
            pre = arr[i][0]
        }
        sum += arr[i][1]
        if(sum === 0){
            temp[0] = pre;
            temp[1] = arr[i][0]
            res.push([...temp])
            pre = -1
        }
    }
    return res
};

分享就到这里啦~