56.合并区间

56.合并区间

题目

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

示例 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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解

合并区间类的题目套路,采用贪心思想, 先排序, 然后遍历检查是否满足合并区间的条件

假设区间1、区间2重叠,且区间3和区间1或区间2有重叠。那么区间3和区间1和区间2的并集一定是有重叠的。

那么排序采用哪种顺序?对左右哪个端点进行排序呢?

这里采用对左端点进行从小到大的排序
如区间[1,4]、[2,4]
1.合并区间之后的左端点是确定的,就是前面区间的左端点
2.判断区间重叠只用判断i的右端点是否大于等于i+1的左端点
3.合并区间的右端点是取区间右端点大的值

代码

class Solution {
    public int[][] merge(int[][] intervals) {
        int len = intervals.length;
        if(len==1) return intervals;
        Arrays.sort(intervals,(o1,o2)->Integer.compare(o1[0],o2[0]));
         List<int[]> res = new ArrayList<>();
         int left = intervals[0][0];
         int right = intervals[0][1];
         for(int i=1;i<len;i++){
             if(right>=intervals[i][0]){ //表示有重叠区间,左端点不变,右端点选大的值
                 right = Math.max(right,intervals[i][1]);
             }else{//表示没有重叠区间,先加入结果集,再更新左右端点
                 res.add(new int [] {left,right});
                 left = intervals[i][0];
                 right = intervals[i][1];
             }
         } //出循环的时候,不管最后一个元素有没有合并,最后一次的left和right都是没有加入结果集的
         res.add(new int [] {left,right});
         return res.toArray(new int[res.size()][2]);
    }
}

补充1
结果集不直接初始化为动态数组的原因:没办法判断长度,所以不能创建二维数组
补充2
有关区间的题,可以用双指针

posted @ 2021-08-09 16:36  rananie  阅读(55)  评论(0编辑  收藏  举报