题目
https://leetcode-cn.com/problems/merge-intervals/
class Solution {
public int[][] merge(int[][] intervals) {
//按区间起点,进行排序
Arrays.sort(intervals,(x,y)->(x[0]-y[0]));
ArrayList<int[]> res=new ArrayList<>();//存放结果
res.add(intervals[0]);//将第一个区间放入
for(int i=1;i<intervals.length;i++){
int[] before=res.get(res.size()-1);//获取最后一个区间
if(before[1]>=intervals[i][0]){
//前一个的右边界,大于等于,当前的左边界。说明有重叠
//合并区间
before[1]=Math.max(before[1],intervals[i][1]);
}
else{
//无重叠
res.add(intervals[i]);
}
}
return res.toArray(new int[res.size()][2]);
}
}
class Solution {
public int[][] merge(int[][] intervals) {
int len=intervals.length;
if(len==0) return new int[0][2];
Arrays.sort(intervals,new Comparator<int[]>(){
public int compare(int[] p1,int[] p2){
if(p1[0]!=p2[0])
return p1[0]-p2[0];
else
return p1[1]-p2[1];
}
});
int[] before=intervals[0];
ArrayList<int[]> list=new ArrayList<>();
for(int i=1;i<len;i++){
int[] cur=intervals[i];
if(before[1]<cur[0]){
list.add(before);
before=cur;
}
else if(before[1]==cur[0]){
before[1]=cur[1];
}
else{
if(cur[1]<=before[1]){
//before的前后不变
}
else{
before[1]=cur[1];
}
}
}
list.add(before);
int[][] res=new int[list.size()][2];
for(int i=0;i<list.size();i++){
res[i]=list.get(i);
}
return res;
}
}
分析
对每个区间的左边界进行升序的排序。然后遍历所有区间,如果前一个区间的右边界<=后一个区间的左边界,则表示它们有重叠,进行合并。
注意:前一个区间的右边界可能>当前区间的右边界,
所以要Math.max(list.get(list.size()-1)[1],intervals[i][1]) 选较大值。
不然就会出现这样的错误↓
代码
class Solution {
public int[][] merge(int[][] intervals) {
ArrayList<int[]> list=new ArrayList<int[]>();
Arrays.sort(intervals,(x,y)->(x[0]-y[0]));//排序
for(int i=0;i<intervals.length;i++){
//不重叠
if(list.size()==0||list.get(list.size()-1)[1]<intervals[i][0]){
//直接加入
list.add(new int[]{intervals[i][0],intervals[i][1]});
}
//有重叠,修改上一个区间为合并当前区间后的
else{
list.get(list.size()-1)[1] = Math.max(list.get(list.size()-1)[1],intervals[i][1]);
}
}
return list.toArray(new int[list.size()][]);
}
}
复杂度
时间复杂度:O(nlogn),其中 n 为区间的数量。除去排序的开销,我们只需要一次线性扫描,所以主要的时间开销是排序的 O(nlogn)。
空间复杂度:O(logn),其中 n 为区间的数量。这里计算的是存储答案之外,使用的额外空间。O(logn) 即为排序所需要的空间复杂度。