Leetcode 630. 课程表 III
题目
这里有 n 门不同的在线课程,他们按从 1 到 n 编号。每一门课程有一定的持续上课时间(课程时间)t 以及关闭时间第 d 天。一门课要持续学习 t 天直到第 d 天时要完成,你将会从第 1 天开始。
给出 n 个在线课程用 (t, d) 对表示。你的任务是找出最多可以修几门课。
示例:
输入: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]]
输出: 3
解释:
这里一共有 4 门课程, 但是你最多可以修 3 门:
首先, 修第一门课时, 它要耗费 100 天,你会在第 100 天完成, 在第 101 天准备下门课。
第二, 修第三门课时, 它会耗费 1000 天,所以你将在第 1100 天的时候完成它, 以及在第 1101 天开始准备下门课程。
第三, 修第二门课时, 它会耗时 200 天,所以你将会在第 1300 天时完成它。
第四门课现在不能修,因为你将会在第 3300 天完成它,这已经超出了关闭日期。
提示:
- 整数 1 <= d, t, n <= 10,000 。
- 你不能同时修两门课程。
题解
贪心、优先队列
我们将d作为第一关键字进行升序排序,将t作为第二关键字进行升序排序。优先队列为课程学习时间的大顶堆。
我们遍历课程表,我们用一个遍历记录学习课程的时间,如果学习时间+当前课程学习时间<当前课程结束时间,我们就直接放入优先队列中;否则,若堆顶大于当前课程学习时间,我们就pop顶,push当前。详细过程见代码
代码
bool sortCourse(vector<int>& c1,vector<int>& c2){
if(c1[1]==c2[1]) return c1[0]<c2[0];
return c1[1]<c2[1];
}
class Solution {
public:
int scheduleCourse(vector<vector<int>>& courses) {
int n = courses.size();
sort(courses.begin(),courses.end(),sortCourse);
priority_queue<int> q;
int day=0;
for(int i=0; i<n; i++){
if(day+courses[i][0]<=courses[i][1]){
q.push(courses[i][0]);
day += courses[i][0];
}else if(!q.empty() && q.top()>courses[i][0]){
day -= q.top();
q.pop();
day += courses[i][0];
q.push(courses[i][0]);
}
}
return q.size();
}
};
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/course-schedule-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。