题目
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
数据范围
1 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <=endi <= 104
测试用例
示例1
java
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例2
java
输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
示例3
java
输入:intervals = [[4,7],[1,4]]
输出:[[1,7]]
解释:区间 [1,4] 和 [4,7] 可被视为重叠区间。
题解1(博主思路,差分,时间复杂度(max(O(N),O(M)))
java
class Solution {
public static int b[];
public int[][] merge(int[][] intervals) {
// 1. 初始化差分数组
b = new int[20005];
List<int[]> list = new ArrayList<>();
int n = intervals.length;
int tn = n;
int ti = 0;
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
// 2. 差分处理
while(tn-- != 0){
int l = intervals[ti][0] * 2; // 二倍坐标
int r = intervals[ti][1] * 2;
b[l]++;
b[r+1]--;
ti++;
min = Math.min(min, l);
max = Math.max(max, r);
}
// 3. 计算前缀和
for(int i = min; i <= max + 1; i++){
if(i>=1)
b[i] += b[i-1];
}
// 4. 收集结果
int tl = min;
for(int i = min; i <= max + 1; i++){
// 如果 b[i] 归零,说明一段连续区间结束了
if(b[i] == 0 && i - tl > 0){
list.add(new int[]{tl / 2, (i - 1) / 2});
tl = i + 1;
} else if(b[i] == 0 && i - tl <= 0){
tl = i + 1;
}
}
return list.toArray(new int[list.size()][]);
}
}
题解2(官方题解,时间复杂度O(nlogn))
java
class Solution {
public int[][] merge(int[][] intervals) {
if (intervals.length == 0) {
return new int[0][2];
}
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
List<int[]> merged = new ArrayList<int[]>();
for (int i = 0; i < intervals.length; ++i) {
int L = intervals[i][0], R = intervals[i][1];
if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < L) {
merged.add(new int[]{L, R});
} else {
merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], R);
}
}
return merged.toArray(new int[merged.size()][]);
}
}
思路
这道题相对来说比较简单,数据集量少,规模小,直接排序遍历(O(nlogn))就能满足时间复杂度,唯一就是需要处理一下合并的逻辑关系,因为只有重叠才合并而并非相邻,所以需要者一点,但并不难。
但如果这道题数据量大应该如何处理呢,博主的思路是差分(不知道差分的朋友可以看一下我之前的博客),可以在O(n)的时间复杂度度数据进行处理,然后遍历一遍数组即可,但同样需要注意,由于重叠才合并的关系,我们不能直接使用处理后的差分数组b,我们需要做一点小处理。也就是对所有范围*2,例如1-4与5-6,乘以2后就会被拉开,变为2-8,10-12,不再相邻,可以解决重叠问题。
相关链接
https://blog.csdn.net/qq_62235017/article/details/136778476?spm=1011.2415.3001.5331