难度:中等
给出一个区间的集合,请合并所有重叠的区间。
示例 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]
分析:
如果我们按照区间的左端点排序,那么在排完序的列表中,可以合并的区间一定是连续的。如下图所示,标记为蓝色、黄色和绿色的区间分别可以合并成一个大区间,它们在排完序的列表中是连续的:
我们用链表res存储最终的答案。
首先,我们将列表中的区间按照左端点升序排序。然后我们将第一个区间加入 res中,并按顺序依次考虑之后的每个区间:
- 如果当前区间的左端点在res中最后一个区间的右端点之后,那么它们不会重合,我们可以直接将这个区间加入res的末尾;
- 否则,它们重合,我们需要用当前区间的右端点更新res中最后一个区间的右端点,将其置为二者的较大值。
代码:
public int[][] merge(int[][] intervals) {
List<int[]> res = new ArrayList<>();
if(intervals.length == 0)
return res.toArray(new int[0][]);
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] - o2[0];
}
});//比较每行区间的左坐标值
int index=0;
res.add(intervals[0]);
for (int i = 1; i < intervals.length; i++) {
int left = intervals[i][0];
int right = intervals[i][1];
if(res.get(index)[1] < left){
res.add(new int[]{left,right});
index++;
}else {
res.get(index)[1] = Math.max(right,res.get(index)[1]);
}
}
return res.toArray(new int[index+1][]);
}
结果: