【每日一题】课程表 III

Tag

【贪心】【优先队列】【数组】【2023-09-11】


题目来源

630. 课程表 III


题目解读

n 门编号从 1n 的课程,有一个数组 courses,其中 courses[i] = [duration, lastDay] 表示第 i 门课将会持续上 duaration 天,并且必须在 lastDay 之前完成(包括这一天)。你的学期从第一天开始,且不能同时上两门及以上的课程,返回你最多可以修完多少门课程。


解题思路

方法一:贪心+优先队列

为了尽可能多的学习课程,我们优先学习 lastDay 靠前的课程。如果当前课程的结束时间和 lastDay 有冲突了,并且前面学习过的课程中持续时间最长的课程持续时间大于当前课程,就用当前课程替换掉学习过的课程中持续时间最长的课程。

具体地,首先需要对 courses 课程进行按照 lastDay 字段进行升序排序;接着维护一个优先队列 q 用来存放可以学习的课程,如果遇到冲突,直接 q.top() 取出的就是学习过的课程中持续时间最长的课程,如果学习过的课程中持续时间最长的课程的持续时间大于当前课程的持续时间,则用当前课程的持续时间替换之。最后返回 q 的长度即为可以学习的课程数量的最大值。

实现代码

class Solution {
public:
    int scheduleCourse(vector<vector<int>>& courses) {
        sort(courses.begin(), courses.end(), [](const auto& c1, const auto& c2) {
            return c1[1] < c2[1];  
        });

        priority_queue<int> q;
        int total = 0;      // 学习过课程的总时间节点
        for (const auto& course : courses) {
            int t = course[0], d = course[1];
            if (total + t <= d) {
                total += t;
                q.push(t);
            }
            else if (!q.empty() && q.top() > t) {
                total -= q.top();
                total += t;
                q.pop();
                q.push(t);
            }
        }
        return q.size();
    }
};

复杂度分析

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn),排序需要的时间为 O ( n l o g n ) O(nlogn) O(nlogn)。优先队列单次需要 O ( l o g n ) O(logn) O(logn) 的时间,每个课程最多被取出或放入队列一次,因此时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)。总的时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)

空间复杂度: O ( n ) O(n) O(n),是优先队列需要使用的空间。


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wang_nn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值