题目描述
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
贪心解法
先排序,让所有的相邻区间尽可能的重叠在一起,按左边界,或者右边界排序都可以,处理逻辑稍有不同。
按照左边界从小到大排序之后,如果 intervals[i][0] <= intervals[i - 1][1] 即intervals[i]的左边界 <= intervals[i - 1]的右边界,则一定有重叠。(本题相邻区间也算重贴,所以是<=)。
最后合并,合并区间后左边界和右边界,作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。
class Solution {
public int[][] merge(int[][] intervals) {
// 创建一个链表来存储合并后的区间
LinkedList<int[]> res = new LinkedList<>();
// 对区间数组按照起始点进行排序
Arrays.sort(intervals, (o1, o2) -> Integer.compare(o1[0], o2[0]));
// 将第一个区间加入结果列表
res.add(intervals[0]);
int len = intervals.length;
// 遍历从第二个区间开始的所有区间
for (int i = 1; i < len; i++) {
// 如果当前区间的起始点小于等于结果列表中最后一个区间的终点,说明有重叠
if (intervals[i][0] <= res.getLast()[1]) {
// 获取结果列表中最后一个区间的起始点
int start = res.getLast()[0];
// 计算当前区间和结果列表中最后一个区间的最大终点
int end = Math.max(intervals[i][1], res.getLast()[1]);
// 移除结果列表中最后一个区间
res.removeLast();
// 将合并后的区间加入结果列表
res.add(new int[] { start, end });
} else {
// 如果当前区间和结果列表中最后一个区间没有重叠,直接加入结果列表
res.add(intervals[i]);
}
}
// 将链表转换为二维数组返回
return res.toArray(new int[res.size()][]);
}
}