1. 删除被覆盖区间
先来看与合并区间比较相似的一道题目:删除被覆盖的区间
思路:
- 起点按照升序排序,终点按照降序排序
- 基于以上排序规则,相邻的两个区间会有以下三种情况:
- 第一种情况:找到一个覆盖区间,结果+1
- 第二种情况:合并成一个大区间
- 第三种情况:更新边界
注意事项:
- 用Lambda表达式箭头函数对区间进行排序 (参数类型 参数名称) ‐> { 代码语句 }
class Solution {
public int removeCoveredIntervals(int[][] intervals) {
Arrays.sort(intervals,(int[] interval1, int[] interval2)->{
if(interval1[0]!=interval2[0]) { // 区间起点升序排列
return interval1[0] - interval2[0];
}else{
return interval2[1]-interval1[1]; // 起点相同时,终点降序排列
}
});
int left=intervals[0][0];
int right=intervals[0][1];
int cover=0;
for(int i=1;i<intervals.length;i++){
if(left<=intervals[i][0] && right>=intervals[i][1]){
cover++;
}else if(left<=intervals[i][0] && right<=intervals[i][1]) { // 合并
right=intervals[i][1];
}else if(right<intervals[i][0]){ // 更新
left=intervals[i][0];
right=intervals[i][1];
}
}
return intervals.length-cover;
}
}
- 🍓为什么只有三种情况呢,这是因为在起点升序,终点降序之后,排除了很多可能性。当然也可以反过来按照起点升序,终点降序排,这样排列只是为了不遗漏。
2. 合并区间
- 需要用可变长数组来存储
- 一定要排序
- res中的最后一个区间要拿出来比较,随时准备更新
- 遍历的下一个区间的start 和 当前res中最后一个区间的终点 的大小
- 遍历的下一个区间的start > 当前res中最后一个区间的终点 :把下一个区间加入到res的最后
- 遍历的下一个区间的start < 当前res中最后一个区间的终点 :更新区间的终点
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, Comparator.comparingInt((int[] interval) -> interval[0])); // 按照起点升序排序
LinkedList<int[]> res=new LinkedList<>();
res.add(intervals[0]);
for(int i=1;i<intervals.length;i++){
if(intervals[i][0]>res.getLast()[1]){ // 加入新区间
res.offerLast(new int[]{intervals[i][0],intervals[i][1]});
}else if(intervals[i][1]>=res.getLast()[1]){ // 在原区间上更新终点
int[] tmp=res.pollLast();
tmp[1]=intervals[i][1];
res.offerLast(tmp);
}
}
int[][] result=new int[res.size()][2];
for(int i=0;i<res.size();i++){
result[i]=res.get(i);
}
return result;
}
}