Day 36 | 435. 无重叠区间 & 763.划分字母区间 & 56. 合并区间

435. 无重叠区间

Day 36 | 435. 无重叠区间 & 763.划分字母区间 & 56. 合并区间_第1张图片

难啊。。。看了一个多小时没理解

贪心:

首先,按照右端点升序排序。

        为什么是右端点呢?因为右端点最小的区间,和别的区间重合的可能性就最小

        然后定义count=1记录不重叠区间的个数,因为第一个区间不与前面重叠因此初值为1(不确定理解的是否正确).定义end初值为nums[0][1]即第一个区间右端点。

        遍历所有区间,每次和下一区间的左端点进行比较,若该区间左端点小于end(即下一区间右端点),说明不重合,count值加一,更新end值为当前不重合区间的右端点

        遍历完毕后count值即为所有区间的最大不重叠个数。用数组长度-count即为移除的最小数量。

    public int eraseOverlapIntervals(int[][] intervals) {
        //按右端点升序排序
        Arrays.sort(intervals,(a,b)->{return a[1]-b[1];});
        int count=1;
        int end=intervals[0][1];
        for(int i=1;i

763.划分字母区间

Day 36 | 435. 无重叠区间 & 763.划分字母区间 & 56. 合并区间_第2张图片

解题思路:

        遍历字符串,记录每个字符在字符串中出现最后一次的下标位置记录在edge数组中。

        再次遍历,设置idx变量记录每次遍历字符的最后一次最大下标,该在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。因为没有比之前出现过的字符没有更大的下标了,前面出现过的字符都被遍历过了。

        定义last值代表上一个划分的位置,初值为-1,每次添加idx-last到结果集中即可。

    public List partitionLabels(String s) {
        List res=new ArrayList<>();
        int[] edge=new int[26];
        char[] chars=s.toCharArray();
        int idx=0;//idx为当前遍历过的字母的最大下标值
        for(int i=0;i

56. 合并区间

Day 36 | 435. 无重叠区间 & 763.划分字母区间 & 56. 合并区间_第3张图片

 看了思路之后自己写出来代码了!开心!

解题思路:

        首先对数组左边界升序排序。

        i从1开始,当前区间的左边界如果小于等于上一区间右边界说明可以合并,则修改当前区间的左右边界为 当前区间和上一区间左区间最小值,右区间最大值。continue继续下一次循环。

        否则说明不可以合并,直接将当前区间添加到结果集即可。

特殊判断:

①若i==length-1时,若可以合并,则合并。不能合并直接添加最后一个区间到结果集即可。

②若数组长度为1,直接返回原数组即可。

    public int[][] merge(int[][] intervals) {
        if(intervals.length==1){
            return intervals;
        }
        Arrays.sort(intervals,(a,b)->{
            return a[0]-b[0];
        });
        List res=new ArrayList<>();
        int right;
        for(int i=1;i

        

你可能感兴趣的:(算法)