算法——LeetCode56. 合并区间

56. 合并区间

原题链接

题目:

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

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

注意:输入类型已于2019年4月15日更改。 请重置默认代码定义以获取新方法签名。

提示:

  • intervals[i][0] <= intervals[i][1]

题解1:排序+遍历比较

主要流程:

  1. 先对数组进行排序,以每个数组的首元素为排序依据
  2. 设定结果集 res ,以一维数组遍历intervals,
  • 若 res 右端点小于 interval 左端点,则开始新的区间
  • 否则 res 右端点大于等于 interval 左端点。合并区间
  1. 由于初始化 res 的大小为 intervals 的大小,合并区间后,
    res 数组会产生不必要的 [0,0] 元素,使用 Arrays.copyOf()删去

代码:

    class Solution {
     
        public int[][] merge(int[][] intervals) {
     
            //对二维数组首元素按升序排列
            Arrays.sort(intervals, new Comparator<int[]>() {
     
                @Override
                public int compare(int[] o1, int[] o2) {
     
                    return o1[0] - o2[0];
                }
            });
            //创建结果数组
            int res[][] = new int[intervals.length][2];
            int idx = -1;//结果集的索引
            //把intervals 看做一个一维数组,其中存储的数据为一维数组
            //这时 interval[0] 相当于 intervals[i][0]
            for (int[] interval : intervals) {
     
                //若res右端点比interval左端点小,不合并区间
                if (idx == -1 || interval[0] > res[idx][1]) {
     
                    res[++idx] = interval;//interval相当于 一维数组,res[] 也为一个一维数组
                } else if (interval[0] <= res[idx][1]) {
     //此时合并区间,res右端点为两者右端点大者
                    res[idx][1] = Math.max(interval[1], res[idx][1]);
                }

            }

            return Arrays.copyOf(res, idx + 1);//截取后面为[0,0]的数组
        }
    }

复杂度分析:

  • 时间复杂度:O(n\log n),其中 nn 为区间的数量。除去排序的开销,我们只需要一次线性扫描,所以主要的时间开销是排序的 O(n\log n)。

  • 空间复杂度:O(\log n),其中 nn 为区间的数量。这里计算的是存储答案之外,使用的额外空间。O(\log n)即为排序所需要的空间复杂度。

参考题解:
https://leetcode-cn.com/problems/merge-intervals/solution/chi-jing-ran-yi-yan-miao-dong-by-sweetiee/

你可能感兴趣的:(算法,数据结构,算法)