LeetCode 56:Merge Intervals
题意描述
给定数字间隔的集合,合并所有重叠的数字间隔。
测试用例
Example 1:
Input: [[1,3],[2,6],[8,10],[15,18]] Output: [[1,6],[8,10],[15,18]] Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
Example 2:
Input: [[1,4],[4,5]] Output: [[1,5]] Explanation: Intervals [1,4] and [4,5] are considered overlapping.
解题思路
一、思路一
- 使用两个数组,一个数组保存所有间隔的起始位置,一个数组保存所有间隔的结束位置,将两个数组排序
- 遍历两个数组,当i+1位置的的起始元素大于i位置的结束元素,说明【start【0】,end【i】】是一个重叠间隔
- 继续向后遍历,下一个重叠间隔的起始位置从i+1开始
- 不要忘记最后一个间隔
public int[][] merge(int[][] intervals) {
if(intervals == null || intervals.length == 0){
return new int[0][];
}
int[] start = new int[intervals.length]; //起始数组
int[] end = new int[intervals.length]; //结束数组
ArrayList<int[]> res = new ArrayList<>(); //使用list保存结果
for(int i=0;i<intervals.length;i++){
start[i] = intervals[i][0];
end[i] = intervals[i][1];
}
Arrays.sort(start);
Arrays.sort(end);
int j = 0; //使用j记录间隔的起始位置
for(int i=0;i<intervals.length-1;i++){
if(start[i+1] > end[i]){ //当下一个间隔的起始位置 》 上一个间隔的结束位置
res.add(new int[]{start[j],end[i]});
j = i+1; //更新间隔的起始位置
}
}
//不要忘记最后一个间隔,因为起始数组遍历到倒数第二个间隔的起始位置
res.add(new int[]{start[j],end[intervals.length-1]});
return res.toArray(new int[res.size()][]);
}
二、思路二
- 将数组中的数组间隔进行排序,使用
Arrays.sort(intervals, Comparator.comparingInt(i -> i[0]));
,这样间隔按开始元素升序排列 - 使用临时数组保存第一个间隔,如果下一个间隔的开始元素小于上一个间隔的结束元素,说明有重叠,将结束元素更新为两个间隔结束元素的最大值
- 如果两个间隔没有重叠,更新临时数组为下一间隔,并且直接将下一个间隔加入List集合
public int[][] merge(int[][] intervals) {
if(intervals == null || intervals.length == 0)
return new int[0][];
//按开始元素升序排列
Arrays.sort(intervals, Comparator.comparingInt(i -> i[0]));
List<int[]> list = new ArrayList<>();
//保存当前间隔
int[] newintervals = intervals[0];
list.add(newintervals);
for(int[] interval:intervals){
//有重叠
if(interval[0] <= newintervals[1]){
newintervals[1] = Math.max(interval[1],newintervals[1]);
}else{ //无重叠
newintervals = interval;
list.add(newintervals);
}
}
return list.toArray(new int[list.size()][]);
}