2.<tag-数组>-leetcode.56-合并区间Java实现 3

1. LeetCode 56. 合并区间 (Medium)

[案例需求]
以数组 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

[思路分析]

  1. 读题知, 本道题中的参数是一个二维数组, 其中的元素是一个又一个的一维数组, 又因为要求是一个区间, 所以这个一维数组只有两个元素, 索引毫无疑问均为0 和1;

  2. 首先我们本着简化问题的原则, 第一步就需要对二维数组中的一维数组进行排序, 如何排序? 对每一个一维数组的第一个数(或者说是每个区间的左区间)排序即可

  3. 当我们排好序后, 左区间就是升序排列了, 这时候我们需要考虑每两个区间进行比较, 得出这两个区间是否重叠, 如果两区间重叠就合并之;

  4. 如何判别两区间重叠呢? 如果第一个区间的右区间 >= 第二个区间的左区间,那么这两个区间就是重叠的, 反之就不是重叠的;

  5. 有人可能会有疑问, 那如果第二个区间的右区间同样也小于第一个区间的右区间呢? 这个也是重叠的一种情况, 所以我们会在3的情况下, 进一步比较第一个区间的右区间 和 第二个区间的右区间, 最大者将会被覆盖到第一个区间的右区间中;

  6. 逻辑搞清楚之后, 就是一些实现细节啦, 因为合并后的区间数量是动态的, 毫无疑问, 可以使用集合去存储每一次合并后的区间(一维数组), 直到最后把集合转为数组返回即可;

  7. 了解大致思想之后, 更具体的实现细节, 请仔细阅读每一步代码, debug一下也是不错的选择;

[代码实现]

public class Solution56 {
        public static int[][] merge(int[][] intervals){
            //使用comparator对区间的左区间进行生序排列
            Arrays.sort(intervals, new Comparator<int[]>(){
                public int compare(int[] arr1, int[] arr2) {
                    return arr1[0] - arr2[0];
                }
            });
            //2. 比较重叠情况,
            2.1 第一个区间, 或者没有重叠的直接放进集合
            ///2.2 如果集合中的最后一个区间的右区间 > 原数组区间的左区间,(叫有重叠)
            //          比较第一个区间右区间和原数组区间的右区间, 把大的更新到集合最后一个区间的右区间中去
            //
            //新建集合
            ArrayList<int[]> outList = new ArrayList<int[]>();
    
            if(outList.size() == 0) outList.add(intervals[0]);
    
    
    
            for(int i = 1; i < intervals.length ; i++){
                int curRightOutList = outList.get(outList.size()-1)[1];
                //如果有重叠, 比较右区间大小, 大的更新右区间或维持不变
                if(curRightOutList >= intervals[i][0]){
                    //集合中最后一个区间的下限(最近刚添加进集合的区间)
                    curRightOutList = Math.max(curRightOutList, intervals[i][1]);
                    outList.get(outList.size()-1)[1] = curRightOutList; //??直接修改集合中的值, 可行?
                }else{
                    outList.add(intervals[i]);
                }
            }
            return outList.toArray(new int[outList.size()][]);
        }
}

在这里插入图片描述

通过本题我们复习到:

  1. 当遇到返回一个数据长度不定的数据,我们不应该直接存到数组, 而是应该先存到集合中去, 因为集合是可变长度的嘛, 如果题目要求返回的是数组, 比如这道题; 此时就会遇到集合和数组相互转换的问题; (单独发文)
  2. 如何对集合排序? Arrays.sort()
    Q: 数组和集合之间怎么转换呀?
    Q: 可变数组
    Q: 如何返回一个长度不确定的数组? 放入集合
    Q: list 取值, list.get(index)
    Q: 集合和数组之间的转换 https://www.cnblogs.com/JohnTeslaaa/p/12573075.html
    Q: 集合之间的排序 方法重写
    Q: 内部类, 内部方法, 重写comparator类, 如何确定升序降序?
    Q: 集合中存放引用数据类型的数组, 这个数组自身发生改变, 那么集合中的数组的值也会发生改变
posted @ 2022-05-26 20:31  青松城  阅读(107)  评论(0编辑  收藏  举报