5.9.贪心算法做区间调度:不重叠区间个数、最少的箭射气球

1.区间调度问题

设计一个算法,算出最多有多少个互不相交的区间?
eg:二维数组intvs = [[1,3],[2,4],[3,6]];最多有两个不相交区间,即[1,3]和[3,6]。

1.题目分析
区间[start, end]

  • 1.先把区间按end的升序进行排列;
  • 2.从前向后选择时,start >= 当前preEnd 的说明是不重叠区间,res+1,然后更新preEnd = 当前end
    2.代码
class Solution {
    public int intervalSchedule(int[][] intervals) {
        if (intervals.length==0) return 0;
         1. 按区间的end升序排列
        Arrays.sort(intervals, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                 按第二个元素升序排列
                return o1[1] - o2[1];
            }
        });

         2.排查,
         排序过后的第一个end就是最小的
        int preEnd = intervals[0][1];
         至少有1int res = 1;
        for (int[] inte: intervals) {
             当前元素的start 大于 此时end时
            if (inte[0] >= preEnd){
                res++;
                 更新preEnd
                preEnd = inte[1];
            }
        }
        return res;
    }
}

435. 无重叠区间

在这里插入图片描述
1.题目分析

  • 由上一题可知,区间总数 减去 上一题的返回值,就是本题的答案

2.代码

class Solution {
    public int eraseOverlapIntervals(int[][] intervals) {
        if (intervals.length==0) return 0;
        int len = intervals.length;
        return len - intervalSchedule(intervals);
    }
}

452. 用最少数量的箭引爆气球

在这里插入图片描述
在这里插入图片描述
1.题目分析

  • 1.先按end进行升序排列;
  • 2.遍历时,start < preEnd 的是一组,他们被同一支箭戳破;res++
  • 3.然后用这组最后一个元素的下一个元素的end新preEnd;

注意:
在这里插入图片描述

2.代码

class Solution {
    public int findMinArrowShots(int[][] points) {
        if (points==null || points.length == 0)
            return 0;
        按end的升序排列
        Arrays.sort(points, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
            
                return o1[1] >= o2[1] ? 1 : -1;
            }
        });
        
        int res = 1;
        int preEnd = points[0][1];
        int len = points.length;
        for (int i = 0; i < len; i++) {
            int start = points[i][0];
            此时,它们可以被一只箭戳破
            if (start <= preEnd){
                continue;
            }
            此时进入下一只箭
            else if (start > preEnd){
                res++;
                preEnd = points[i][1];
            }
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值