“最多可以参加的会议数目”

题目一:给你一个数组 events,其中 events[i] = [startDayi, endDayi] ,表示会议 i 开始于 startDayi ,结束于 endDayi 。

你可以在满足 startDayi <= d <= endDayi 中的任意一天 d 参加会议 i 。注意,一天只能参加一个会议。

请你返回你可以参加的 最大 会议数目。

记录题解:

贪心思路:按照会议结束时间最小的优先排,因为结束时间靠后的 “战线” 拉的长,可以排后面,前面的天数可以让给结束时间短的会议优先排

大白画:统计当天为起始时间的所有会议,选取其中结束时间最早的那个会议

首先需要按照起始时间对 events 数组进行升序排列,使得起始时间相同的会议放在一起,避免后面在统计当天为起始时间的会议时,每统计一天,都要对 events 数组进行遍历。排序后,我们可以维护一个变量,遍历并标记 events 的位置,使得 events 在统计完所有天的会议后之遍历一遍。

这里需要维护动态变化(考虑到过期会议)的结束时间的最小值,可以使用小顶堆来维护。

过期会议:可能已经有未排的会议的结束时间在当天之前,这时我们需要将过期会议的结束时间从小顶堆中移除。

class Solution {
    public int maxEvents(int[][] events) {
        int res = 0;
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        Arrays.sort(events,new Comparator<int[]>(){
            public int compare(int[] a1,int[] a2){
                return a1[0] - a2[0];
            }
        });  
    int i = 0, n = events.length,curDay = 1;
    while(i < n || !pq.isEmpty()){
        //将curDay这一天为起始时间的会议加入优先级队列
        while(i < n && curDay <= events[i][1] && curDay >= events[i][0]){
            pq.offer(events[i][1]);
            i++;
        }
        //移除过期的
        while(!pq.isEmpty() && curDay > pq.peek()){
            pq.poll();
        }
        //从剩下的选出结束时间最小的作为curDay 的会议
        if(pq.peek() != null){
            res++;
            pq.poll();
        }
    
        //选下一天的会议
        curDay++;
    }
    return res;

    }
}

注:java 中 PriorityQueue (优先级队列)默认就是小顶堆结构

题目二:一些项目要占用一个会议室宣讲,会议室不能同时容纳两个项目的宣讲。给你一个项目开始的时间(给你一个数组,里面是一个个具体的项目), 你来安排宣讲的日程,要求会议室进行的宣讲的场次最多。返回最多场次

 

class Event{
    public int start;//会议开始时间
    public int end;//会议结束时间
}

class Greedy{

    public int bestArrange(Event[] events){
        //按结束时间排序
        int res = 0;
        int temp = 0;
        Arrays.sort(events,new Comparator<Event>(){
            public int compare(Event e1,Event e2){
                return e1 - e2;
            }
        });

        for(int i = 0; i < events.length; i++){
            //判断一下个会议是否过期,这里不同于第一题,第一题时一个会议开一天,此题会议的持续时间不定,是某一个时间段,所以要判断star会议起始时间是否过期
            if(temp <= events[i + 1].start){
                res++;
                temp = events[i + 1].end;
            }
        }
        return res;
        
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值