代码随想录算法训练营day36 | 435. 无重叠区间,763.划分字母区间,56. 合并区间

代码随想录算法训练营day36 | 435. 无重叠区间,763.划分字母区间,56. 合并区间


435. 无重叠区间

教程视频:https://www.bilibili.com/video/BV1A14y1c7E1/?spm_id_from=333.788&vd_source=ddffd51aa532d23e6feac69924e20891
在这里插入图片描述
本题其实和上题452.用最少数量的箭引爆气球非常像,弓箭的数量就相当于是非交叉区间的数量。
本题求的则是交叉区间的数量,修改上题的边界条件和计数位置即可。

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        //按照左边界升序排列
        Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
        int count=0;
        for(int i=1; i<intervals.length; i++){
            if(intervals[i-1][1]<=intervals[i][0]){
                continue;
            }else{
                //前两个有交叉
                count++;
                //删除长的区间
                intervals[i][1]=Math.min(intervals[i-1][1],intervals[i][1]);
            }
        }
        return count;
    }
}

763.划分字母区间

教程视频:https://www.bilibili.com/video/BV18G4y1K7d5/?spm_id_from=pageDriver&vd_source=ddffd51aa532d23e6feac69924e20891
在这里插入图片描述

分为如下两步:
	1、统计每一个字符最后出现的位置
	2、从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
class Solution {
    public List<Integer> partitionLabels(String s) {
        //统计每个字符最大索引
        int[] maxIndex = new int[26];
        for(int i=0;i<s.length();i++){
            maxIndex[s.charAt(i)-'a'] = i;
        }
        List<Integer> result = new ArrayList<>();
        int left=0;
        int right = 0;
        for(int i=0;i<s.length();i++){
           right= Math.max(right,maxIndex[s.charAt(i)-'a']);//记录当前最远索引
            if(i==right){
                result.add(right-left+1);
                left = right+1;
            }
        }
        return result;
    }
}

56. 合并区间

教程视频:https://www.bilibili.com/video/BV1wx4y157nD/?spm_id_from=333.788&vd_source=ddffd51aa532d23e6feac69924e20891
在这里插入图片描述

先排序,让所有的相邻区间尽可能的重叠在一起。下文代码是根据左边界升序排序的。
遍历每个区间,如果区间未重叠,直接加入结果数组;
区间重叠,更新当前最小左边界和最大右边界,继续向后遍历。

class Solution {
    public int[][] merge(int[][] intervals) {
         //按照左边界排序
        Arrays.sort(intervals,(a,b)->Integer.compare(a[0],b[0]));
         List<int[]> res = new LinkedList<>();
        for(int i=1;i<intervals.length;i++){
            if(intervals[i-1][1]<intervals[i][0]){
                //没有重叠
                res.add(intervals[i-1]);
            }else{
                //更新最小左边界和最大右边界
                intervals[i][0] = intervals[i-1][0];
                intervals[i][1]=Math.max(intervals[i-1][1],intervals[i][1]);
            }
        }
        res.add(intervals[intervals.length-1]);
        return res.toArray(new int[res.size()][]);
    }
}

总结

关于区间重合的题目,首先要进行排序,相邻区间尽可能的重叠;
然后判断是寻找重合区间还是非重合区间,确定处理逻辑;
最后编写程序还要注意边界的界定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值