《LeetCode之每日一题》:235.课程表 III

课程表 III


题目链接: 课程表 III

有关题目

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

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

返回你最多可以修读的课程数目。
示例 1:

输入:courses = [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]]
输出:3
解释:
这里一共有 4 门课程,但是你最多可以修 3 门:
首先,修第 1 门课,耗费 100 天,在第 100 天完成,在第 101 天开始下门课。
第二,修第 3 门课,耗费 1000 天,在第 1100 天完成,在第 1101 天开始下门课程。
第三,修第 2 门课,耗时 200 天,在第 1300 天完成。
第 4 门课现在不能修,因为将会在第 3300 天完成它,这已经超出了关闭日期。
示例 2:

输入:courses = [[1,2]]
输出:1
示例 3:

输入:courses = [[3,2],[4,3]]
输出:0
提示:

1 <= courses.length <= 10^4
1 <= durationi, lastDayi <= 10^4

题解

法一:优先队列 + 贪心
参考官方题解

class Solution {
public:
    int scheduleCourse(vector<vector<int>>& courses) {

        //按照lastDay从小到大排序courses数组
        sort(courses.begin(), courses.end(), [](const auto& c0, const auto& c1){
            return c0[1] < c1[1];
        });

        priority_queue<int> q;//优先队列存放所有的可以修读的科目

        //统计优先队列中的所有总时间
        int total = 0;

        for (auto &c : courses)
        {
            int d1 = c[0], l1 = c[1];
            if (total + d1 <= l1)//即将添加的课程d1持续的时间 与 总时间之和 小于等于 截止日期
            {
                total += d1;
                q.push(d1);
            }

            //当前课程 需要持续的时间小于优先队列(大根堆)队头元素
            //我们贪心的将其替换为 d1,这样就可以减少total的上限,增加了可以选择其他科目的可能性
            else if (!q.empty() && q.top() > d1)
            {
                total -= q.top() - d1;
                q.pop();
                q.push(d1);
            }
        }

        return q.size();
    }
};

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值