56. 合并区间(贪心)
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-intervals
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
思路
贪心法,类似看电视节目;按照起始时间排序,然后比较前一个结束时间与当前循环元素起始时间;
若前一个结束时间小于当前循环元素起始时间,说明两者之间没有时间重叠,继续下一轮循环即可;
反之两者之间有交叉,需要将前一个元素的结束时间与当前循环元素的结束时间比较取较大值作为两者合并后的新的区间右边界,然后继续循环。
数组用法小结
//res.toArray栈数组转换为二维数组
//List<int[]> res = new LinkedList<>();//声明集合数组
使用Arrays.sort对二维数组分别按行和列排序(Java):
https://blog.csdn.net/chao_ji_cai/article/details/100072293
代码
/*
//res.toArray栈数组转换为二维数组
//List<int[]> res = new LinkedList<>();//声明集合数组
使用Arrays.sort对二维数组分别按行和列排序(Java):
https://blog.csdn.net/chao_ji_cai/article/details/100072293
贪心法,类似看电视节目;按照起始时间排序,然后比较前一个结束时间与当前循环元素起始时间;
若前一个结束时间小于当前循环元素起始时间,说明两者之间没有时间重叠,继续下一轮循环即可;
反之两者之间有交叉,需要将前一个元素的结束时间与当前循环元素的结束时间比较取较大值作为两者合并后的新的区间右边界,然后继续循环。
*/
class Solution {
public int[][] merge(int[][] intervals) {
int len = intervals.length;
if(len < 2){
return intervals;
}
//sort(T[] a,int from,int to, Comparator c)
//使用lambda表达式,对行:Arrays.sort(arr, Comparator.comparingInt(o -> o[0]));
// 按照起点排序
Arrays.sort(intervals, Comparator.comparingInt(o -> o[0]));
// //等价于下面的循环,但是代码通不过,就很迷
// for (int i = 0; i < len; i++) {
// Arrays.sort(intervals[i]);
// }
List<int[]> res = new LinkedList<>();
res.add(intervals[0]);
for(int i = 1; i < len; i++){
int[] curInterval = intervals[i];
int[] curRes = res.get(res.size() - 1);
if(curRes[1] < curInterval[0]){//前一元素右端点小于当前元素左端点,无交集
res.add(curInterval);
}
else{//有交集的话,合并后元素右端点取两者右端点较大值
curRes[1] = Math.max(curRes[1], curInterval[1]);
}
}
return res.toArray(new int[res.size()][]);//转换成题目要求的二维数组
}
}