引入
56.合并区间
给出一个区间的集合,请合并所有重叠的区间。
示例 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] 可被视为重叠区间。
该题的输入是int[][]的二维数组intervals,其intervals.length就是区间的长度,intervals[0].length长度是2,即表示区间的开始和结束。
首先拿到这道题的时候,需要去充分理解什么样子的区间才能够合并,显然就是后一个区间的开始要小于等于前一个区间的结束,比如[1,3],[2,4],2<3,所以可以合并。并且,合并后的结果就是[1,4]。但是如果是[1,3]和[2,2],其合并结果是[1,3]。也就是后面一个结果,取决于两者比较后的大小。
理解到这点后,还需要考虑,如果出现3个以上的区间都能够合并,它的情况是什么样子的?比如,[1,4],[2,3],[3,5],其合并的结果与先合并[1,4],[2,3]再合并[3,5]的结果是相同的。
题解
所以,首先,需要把该序列,进行一个排序,由于排序的是二维数组,我们可以用Java8的Lambda表达式进行排序(重写Comparator接口里面的compare方法,用Lambda表达式写比较简洁)。
Arrays.sort(intervals,(o1,o2)->o1[0]-o2[0]);
那么,我们现在需要对区间进行一个类似于栈的存取。这里可以使用栈、可以使用LinkedList或者ArrayList,都不妨碍。只不过用栈的时候,输出需要从后往前排列。
由于区间是成对出现的,我们需要有一个新的类来存储它,这里我们是这样写的:
class Interval{
public int x;
public int y;
public Interval(int x,int y){
this.x=x;
this.y=y;
}
}
现在,只需要对数组进行出栈和入栈的类似操作即可:
class Solution {
class Interval{
public int x;
public int y;
public Interval(int x,int y){
this.x=x;
this.y=y;
}
}
public int[][] merge(int[][] intervals) {
//二维数组排序
Arrays.sort(intervals,(o1,o2)->o1[0]-o2[0]);
List<Interval> merged=new ArrayList<Interval>();
for(int i=0;i<intervals.length;i++){
int size=merged.size();
if(size==0||merged.get(size-1).y<intervals[i][0]){
//不能合并,加入新元素
merged.add(new Interval(intervals[i][0],intervals[i][1]));
}else{
//合并
Interval curr=merged.get(size-1);
int bigger=intervals[i][1]>curr.y?intervals[i][1]:curr.y;
merged.set(size-1,new Interval(curr.x,bigger));
}
}
int[][] output=new int[merged.size()][2];
for(int i=0;i<merged.size();i++){
output[i][0]=merged.get(i).x;
output[i][1]=merged.get(i).y;
}
return output;
}
}