Leetcode 630 课程表 III

题目

这里有 n 门不同的在线课程,按从 1 到 n 编号。给你一个数组 courses ,其中 courses[i] = [durationi, lastDayi] 表示第 i 门课将会 持续 上 durationi 天课,并且必须在不晚于 lastDayi 的时候完成。

你的学期从第 1 天开始。且不能同时修读两门及两门以上的课程。

返回你最多可以修读的课程数目。

解题思路

  反悔贪心。贪心策略为,在尽可能短的时间内学习最多的课,对于学习相同数目的课,需要消耗的时间尽可能的少。

  首先是 在尽可能短的时间内学最多的课 ,需要对所有可能的截止时间进行升序排序,对于截止时间一样的课对课程时长进行升序排序。维护一个 nowTime 表示当前已经选择可能的总时长,如果 nowTime + courses[i][0] <= courses[i][1] 表示当前课程可以学习。

  然后对于 学习相同数目的课,需要消耗的时间尽可能的少 ,如果遇到的课程当前可能无法学习,但在已经选择的课程中,如果存在课程时长比当前遇到的课程时长要长的,说明选择当前课程更优,因为更长的截止时间内能学习一样的课程数量而且学习的总时间更短。那么就需要我们维护一个优先队列,把已经选择的课程中最长的课程时长置于队首,便于判断。具体见代码。

代码
class Solution {
    public int scheduleCourse(int[][] courses) {
        Arrays.sort(courses, (a, b) -> {
            if (a[1] == b[1]) return a[0] - b[0];
            else return a[1] - b[1];
        });

        int nowTime = 0, length = courses.length;
        PriorityQueue<Integer> queue = new PriorityQueue<>((a, b) -> b - a);
        for (int i = 0; i < length; i++) {
            if (nowTime + courses[i][0] <= courses[i][1]) {
                nowTime += courses[i][0];
                queue.add(courses[i][0]);
            } else if (!queue.isEmpty() && courses[i][0] < queue.peek()) {
                nowTime -= queue.poll();
                nowTime += courses[i][0];
                queue.add(courses[i][0]);
            }
        }
        return queue.size();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值