leetcode刷题(66)——56. 合并区间

一、题目

给出一个区间的集合,请合并所有重叠的区间。

示例 1:

输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

示例 2:

输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

二、思路——排序

按照区间的左端点进行排序,那么排序之后,能够合并的区间一定是连续的。比如 [ ( 1 , 9 ) , ( 2 , 5 ) , ( 19 , 20 ) , ( 10 , 11 ) , ( 12 , 20 ) , ( 0 , 3 ) , ( 0 , 1 ) , ( 0 , 2 ) ] [(1,9),(2,5),(19,20),(10,11),(12,20),(0,3),(0,1),(0,2)] [(1,9),(2,5),(19,20),(10,11),(12,20),(0,3),(0,1),(0,2)] 按照左端点排序后 [ ( 0 , 1 ) , ( 0 , 2 ) , ( 0 , 3 ) , ( 1 , 9 ) , ( 2 , 5 ) , ( 10 , 11 ) , ( 12 , 20 ) , ( 19 , 20 ) ] [(0,1),(0,2),(0,3),(1,9),(2,5),(10,11),(12,20),(19,20)] [(0,1),(0,2),(0,3),(1,9),(2,5),(10,11),(12,20),(19,20)] 左端点已经排好序,此时只需关注右端点。从左往右,如果某几个区间的右端点的最大值小于其后一个区间的左端点,说明这里出现断点不能合并,前面的这几个区间就可以合并。比如,前五个区间的右端点的最大值为 9,小于第六个区间的左端点 10,所以前五个区间和第六个区间是不能合并的,合并前五个区间得到 ( 0 , 9 ) (0,9) (0,9);再看,第六个区间的右端点 11 小于第七个区间的左端点 12,所以第六个区间是不能和后面的区间合并的,仍然是 ( 10 , 11 ) (10,11) (10,11);最后合并后两个区间得到 ( 12 , 20 ) (12,20) (12,20)。合并后的结果就是: ( 0 , 9 ) , ( 10 , 11 ) , ( 12 , 20 ) (0,9),(10,11),(12,20) (0,9),(10,11),(12,20)

算法:

我们用一个列表 res 存储最终的答案。

首先,我们将列表中的区间按照左端点升序排序。先拿到第一个区间,left 和 right 分别表示第一个区间的左端点和右端点,取第二个区间与第一个区间比较:

  • 如果第二个区间的左端点小于等于第一个区间的右端点,那么它们重合,我们将 right 修改为两个区间中右端点较大的那一个;

  • 否则,它们不重合,用当前的 left 和 right 构建合成的区间并添加至 res。

继续比较下一个区间……

三、代码

class Solution {
    public int[][] merge(int[][] intervals) {
        ArrayList<int[]> res = new ArrayList<>();
        if(intervals.length == 0 || intervals == null)
            return res.toArray(new int[0][]);
        // 按照区间左端点排序
        Arrays.sort(intervals, new Comparator<int[]>(){
            @Override
            public int compare(int[] a, int[] b){
                return a[0] - b[0];
            }
        });
        int i = 0;
        while(i < intervals.length){
            int left = intervals[i][0];
            int right = intervals[i][1];
            // 有重叠,就修改right
            while(i < intervals.length - 1 && intervals[i + 1][0] <= right){
                right = Math.max(right, intervals[i + 1][1]);
                i++;// 判断下一个区间
            }
            // 没有重叠的时候,用left和right构建合成的区间并添加至res
            res.add(new int[]{left, right});
            i++;// 判断下一个区间
        }
        return res.toArray(new int[0][]);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值