leetcode记录-435-无重叠区间-贪心

本文探讨了如何解决435.无重叠区间问题,介绍了两种有效的算法思路:一种是按照区间的起始点排序并贪心地选择不相交的区间;另一种是按照区间的结束点排序并优选结束更早的区间。通过这两种方法,可以有效地减少区间重叠的数量。
摘要由CSDN通过智能技术生成

435.无重叠区间

在这里插入图片描述

思路

  1. 自己的:自己的思路是,遍历每个元素,对于i对应的元素,如果比j对应的首元素小,当i尾>j首且i尾<j尾,去掉区间j(标志数组对应为1);当i尾>=j尾,去掉区间i。每个区间与其他所有的比较。—— 思路上可行,但是要注意,应该要按照首元素排序,否则可能因为第一个元素起点过大导致结果不同。
  2. 题解的:
    ①元素按照首元素排序,然后从第一个元素开始,让end标志为其尾巴,如果后面的元素头>=end,证明没有相交,且因为按头排序的,所以一个一个比较遇到的正好是第一个满足这种情况的元素,他为下一个不相交区间,end为他的尾巴;如果后面的元素头<end,证明相交了,此时end为两者尾巴小的那个尾巴(同样情况下尽量尾巴要小),去掉区间数加一。
    ②元素按照尾元素排序,每次尽可能选择尾巴小的。让end为第一个的尾巴,后面的元素,如果头>end,end就为他的尾;如果不是,end不变,因为相交的尾巴肯定比end大,秉承偏好尾巴小,我们直接去掉区间数+1即可。

代码

  1. 自己的(虽然没通过全部用例)
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
       Arrays.sort(intervals,((o1, o2) -> (o1[0]-o2[0])));
        int[] a = new int[intervals.length];
        int flag = 0;
        for (int i = 0; i < intervals.length; i++) {
            for (int j = 0; j<intervals.length; j++) {
                if (j != i &&intervals[i][0]<=intervals[j][0] && a[j]==0 && a[i]==0){
                    if (intervals[i][1]>intervals[j][0] && intervals[i][1]<intervals[j][1]){
                        a[j]=1;
                        flag++;
                        System.out.println(Arrays.toString(intervals[j]));
                    }else if (intervals[i][1]>intervals[j][0] && intervals[i][1]>=intervals[j][1]){
                        a[i]=1;
                        flag++;
                        System.out.println(Arrays.toString(intervals[i]));
                        break;
                    }
                }
            }
        }
        return flag;
    }
}

在这里插入图片描述
这个用例一眼望不到边,但是能到55证明方法可行,只是太笨了。
2. 排序首元素

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
       Arrays.sort(intervals,(o1, o2) -> (o1[0]-o2[0]));
        int end = intervals[0][1];
        int flag = 0;
        for (int i = 1; i < intervals.length; i++) {
            if(end<=intervals[i][0])
                end=intervals[i][1];
            else {
                end=Math.min(end,intervals[i][1]);
                flag++;
            }
        }
        return flag;
    }
}
  1. 排序尾元素
class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
       Arrays.sort(intervals,(o1, o2) -> (o1[1]-o2[1]));
        int flag=0;
        int end=intervals[0][1];
        for (int i = 1; i < intervals.length; i++) {
            if (end<=intervals[i][0])
                end=intervals[i][1];
            else
                flag++;
        }
        return flag;
    }
}

技巧

  1. 数组排序:
    ①升序排一维:Arrays.sort(ints);
    ②升序排一维部分:Arrays.sort(ints, 2, 5);
    ③升序排二维某个下标:Arrays.sort(ints,(o1, o2) -> (o1[1]-o2[1])); 其中[1]指的是下标,按照自己想要的替换。
  2. 时间范围、区间调度等可参考,且题目需要两个方向考虑时思考能否一个方向贪心(从左到右满足某个条件+从右往左满足另一个,某边满足某个条件即可等)。
  3. flag设为初始值,在循环中根据条件flag变更值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值