这里有 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 <= 104
1 <= durationi, lastDayi <= 104
贪心 + 优先队列。
先根据「结束时间」对 courses
升序排列,从前往后考虑每个课程,过程中维护一个总时长 s,对于某个课程 courses[i]
而言,根据如果学习该课程,是否满足「最晚完成时间」条件进行讨论:
- 学习该课程后,满足「最晚完成时间」要求,即 s +
courses[i][0]
<=courses[i][1]
,则进行学习; - 学习该课程后,不满足「最晚完成时间」要求,此时从过往学习的课程中找出「持续时间」最长的课程进行「回退」操作(这个持续时长最长的课程也有可能是当前课程)。
class Solution:
def scheduleCourse(self, courses: List[List[int]]) -> int:
courses.sort(key=lambda x: x[1])
pq = []
s = 0
for d, e in courses:
heappush(pq, -d)
s += d
if s > e:
s += heappop(pq)
return len(pq)
class Solution {
public int scheduleCourse(int[][] courses) {
Arrays.sort(courses, Comparator.comparingInt(a -> a[1]));
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
int s = 0;
for (int[] course : courses) {
int duration = course[0], lastDay = course[1];
pq.offer(duration);
s += duration;
if (s > lastDay) {
s -= pq.poll();
}
}
return pq.size();
}
}
class Solution {
public:
int scheduleCourse(vector<vector<int>>& courses) {
sort(courses.begin(), courses.end(), [](const auto& c0, const auto& c1) {
return c0[1] < c1[1];
});
int s = 0;
priority_queue<int> pq;
for (auto& course : courses) {
int d = course[0], e = course[1];
pq.push(d);
s += d;
if (s > e) {
s -= pq.top();
pq.pop();
}
}
return pq.size();
}
};
func scheduleCourse(courses [][]int) int {
sort.Slice(courses, func(i, j int) bool {
return courses[i][1] < courses[j][1]
})
h := &Heap{}
s := 0
for _, course := range courses {
if d := course[0]; s+d <= course[1] {
s += d
heap.Push(h, d)
} else if h.Len() > 0 && d < h.IntSlice[0] {
s += d - h.IntSlice[0]
h.IntSlice[0] = d
heap.Fix(h, 0)
}
}
return h.Len()
}
type Heap struct {
sort.IntSlice
}
func (h Heap) Less(i, j int) bool {
return h.IntSlice[i] > h.IntSlice[j]
}
func (h *Heap) Push(x interface{}) {
h.IntSlice = append(h.IntSlice, x.(int))
}
func (h *Heap) Pop() interface{} {
a := h.IntSlice
x := a[len(a)-1]
h.IntSlice = a[:len(a)-1]
return x
}