56. 合并区间

题目描述

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

输入输出

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

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

基本思路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
举个例子模拟一下即可理解
[(0,3),(0,1),(0,2),(1,9),(2,5),(10,11),(12,20),(19,20)] #intervals.length = 8
res=[[]]
i = 0
left = 0
right = 3
接下来进入第十行的while循环 会逐一比较每一个数组第一个值和right的大小 eg.0,0,1,2...
而right又取决于数组第二个值的大小 eg.1,2,9,5...
此时left = 0 right = 9 构成了第一个数组对 存进res里边作为数组维度的第一个值

最后输出的时候必须toArray(new int[0][]) 否则
System.out.println(res.getClass());
for(i = 0; i < res.size();i++){
System.out.println(res.get(i) + "");
}

会打印出(是一个引用地址
class java.util.ArrayList
[I@aec6354
[I@1c655221
[I@58d25a40

时间复杂度:$O(nlogn)$ n为区间的数量,除去排序的开销我们只需要一次线性扫描。

空间复杂度:$O(logn)$ n为区间的数量,这里计算的是存储答案之外,使用的额外空间。

java实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public int[][] merge(int[][] intervals) {
List<int[]> res = new ArrayList<int[]>();
if(intervals.length == 0 || intervals == null){
return new int[0][];
}
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);// 这一步的作用是按照intervals[0]进行排序
int i = 0;
while(i < intervals.length) {
int left = intervals[i][0];
int right = intervals[i][1];
while(i < intervals.length - 1 && intervals[i + 1][0] <= right){
i++;
right = Math.max(right, intervals[i][1]);
}
res.add(new int[]{left, right});
i++;
}
return res.toArray(new int[0][]);
}
}