Leetcode 630. 课程表 III(困难)

题意:
这里有 n 门不同的在线课程,他们按从 1 到 n 编号。每一门课程有一定的持续上课时间(课程时间)t 以及关闭时间第 d 天。一门课要持续学习 t 天直到第 d 天时要完成,你将会从第 1 天开始。
给出 n 个在线课程用 (t, d) 对表示。你的任务是找出最多可以修几门课。
思路:
首先我们注意到,每门课程在结束时间前的任意时间都是可以学习的。
所以我们想到:在某一个结束时间节点前,对于相同数量的课,当然要所耗费的时间越少越好,这样后面有新课时才有可能装得下。
贪心思想
首先我们将每门课按结束时间排序,记录当前所选课程耗时,初始now=0
同时维护一个大顶堆,记录当前已经选的课程每门课的耗时情况。
遍历每一门课
如果now+当前课程耗时小于等于这门课程结束时间,说明可以上这个课,直接选上。
如果now+当前课程耗时小于等于这门课程结束时间,说明不可以上这个课,我们从大顶堆里取出最耗时的那门课,比较两门课的耗时情况,取小的。为什么呢?因为这两门课必定有一门上不了,我们贪心就贪在这,让耗时尽可能小,这样后面说不定可以塞进更多的课。
上述情况不要忘记更新now
最终大顶堆的大小就是选上的课程数量

public int scheduleCourse(int[][] courses) {
        Arrays.sort(courses,(a,b)->a[1]-b[1]);//二维数组排序
        PriorityQueue<Integer> priorityQueue=new PriorityQueue<>((a,b)->b-a);//大顶堆初始化
        int now=0;
        for(int i=0;i<courses.length;i++){
            if(now+courses[i][0]<=courses[i][1]){//塞得进课程
                priorityQueue.add(courses[i][0]);
                now+=courses[i][0];
            }else{//塞不进去
                if(priorityQueue.size()==0){
                    continue;
                }
                int temp=priorityQueue.peek();
                if(temp>courses[i][0]){//比较两门课耗时情况取小
                    priorityQueue.poll();
                    priorityQueue.add(courses[i][0]);
                    now=now-temp+courses[i][0];
                }
            }
        }
        return priorityQueue.size();
    }

时间复杂度:O(nlogn)
空间复杂度:O(n)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值