今天的三道题目,都算是 重叠区间 问题,大家可以好好感受一下。 都属于那种看起来好复杂,但一看贪心解法,惊呼:这么巧妙!
还是属于那种,做过了也就会了,没做过就很难想出来。
不过大家把如下三题做了之后, 重叠区间 基本上差不多了
435.无重叠区间
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
int count=0;
int pre=intervals[0][1];//前一个的右边界
for(int i=1;i<intervals.length;i++){
if(pre>intervals[i][0]){
pre=Math.min(pre,intervals[i][1]);//注意要取最小值!!!!!!!因为至少要保留最短的那个区间
count++;
}
else{
pre=intervals[i][1];
}
}
return count;
}
}
763.划分字母区间
class Solution {
public List<Integer> partitionLabels(String s) {
List<Integer> res=new LinkedList<>();
int[] statistics=new int[26];
char[] chars=s.toCharArray();
//记录字母的最远位置
for(int i=0;i<chars.length;i++){
statistics[chars[i]-'a']=i;
}
int index= 0;//一段区间里的第一个值
int last =-1;//一段区间里最后一个值
for(int i=0;i<chars.length;i++){
//看图一下行不通
// int leng=statistics[chars[i]-'a']-i+1;
// res.add(leng);
// i=statistics[chars[i]-'a'];
//
if(last<statistics[chars[i]-'a']){
last=statistics[chars[i]-'a'];
}
if(i==last){
int leng=last-index+1;
res.add(leng);
index=i+1;
}
}
return res;
}
}
56.合并区间
本题相对来说就比较难了。
class Solution {
public int[][] merge(int[][] intervals) {
//左节点从小到大排序
Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
//因为要进行删除所以设定一个链表存放结果,符合条件就加入
LinkedList<int[]> res=new LinkedList<>();
//先将一个节点加入,不断更新其右边界
res.add(intervals[0]);
for(int i=1;i<intervals.length;i++){
if(res.getLast()[1]>=intervals[i][0]){
//更新右边界
int start=res.getLast()[0];
int end=Math.max(intervals[i][1],res.getLast()[1]);
res.removeLast();
res.add(new int[]{start,end});
}else{
res.add(intervals[i]);
}
}
return res.toArray(new int[res.size()][]);
}
}