题目说明
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
示例 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] 可被视为重叠区间。
解答思路
首先需要对每一个二元组进行左右数值从小到大的排序,保障左边的值一定是最小的,这样方便我们找到第一个元素
排序代码:
Arrays.sort(intervals, (x,y)->{
return x[0] - y[0];
});
然后取第一个元组 interval[0] ,进行迭代,下一个元素从intervals[1]开始比较,这里我们先初始化intervals长度的一个结果数组 result,比较result 的右值和intervals的左值判断是该整个元组的加入进来,还是重新整合这两个元组
int [][]result =new int[intervals.length][2];
int count = 0;
result[0] = intervals[0];
for(int k= 1; k < intervals.length; k++){
if(result[count][1] < intervals[k][0]) {
count+=1;
result[count] = intervals[k];
}else{
//说明是可以合并的情况,但是右边的值选择result[count][1]还是intervals[k][0]需要进行大小的判断
int[]mergeTemp = result[count];
result[++count][0] = merge[0];
result[count][1] = Math.max(mergeTemp[1],intervals[k][1]);
}
}
因为可能存在初始化但是因为发生合并没有赋值的元组[0,0],最后一步需要使用数组的拷贝,剔除[0,0]的元素
return Arrays.copyOf(result, index+1);
所以这道题的完整代码如下:
public class MergeIntervals {
public static int[][] merge(int[][] intervals) {
//获取数组长度
int length = intervals.length;
int[][] result = new int[length][2];
//对数组的左端点进行排序
Arrays.sort(intervals,(x,y)->{
return x[0] - y[0];
});
//将第一个值直接放入数组初始化
result[0] = intervals[0];
int count = 0;
for(int i = 1; i < length; i++){
if(intervals[i][0] > result[count][1]){
count+=1;
result[count] = intervals[i];
}else{
//因为左端点排序之后不知道右端点到底是大是小的
result[count][1] = Math.max(intervals[i][1], result[count][1]);
}
}
return Arrays.copyOf(result, count+1);
}
public static void main(String[] args) {
int a[][]={{1,3},{2,6},{8,10},{15,18}};
int [][]res = merge(a);
for (int i=0; i< res.length ; i++) {
for (int j = 0; j < res[i].length; j++) {
System.out.print(res[i][j]+" ");
}
System.out.println();
}
}
}