630. 课程表 III [困难]

116 阅读1分钟

题目

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

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

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

代码

public int scheduleCourse(int[][] courses) {
    // 按照结束时间排序,先选结束时间早的
    Arrays.sort(courses, (a, b) -> (a[1] - b[1]));

    Queue<Integer> queue = new PriorityQueue<Integer>((a, b) -> b - a);

    // day表示时间推移
    int day = 0;
    for (int[] course : courses) {
        // 只有不超过课程的结束时间才能选择
        if (day + course[0] <= course[1]) {
            day += course[0];
            queue.add(course[0]);

        // 如果超过了课程结束时间,这次备选的课程比上次选的课程的duration短,
        // 该备选的课程结束时间比上次课程晚(已经按照结束时间排序),可以退选上次的课
        } else if (!queue.isEmpty() && queue.peek() > course[0]) {
            day = day - queue.poll() + course[0];
            queue.add(course[0]);
        }
    }
    return queue.size();
}