Leetcode 630 课程表 III

题目

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

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

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

解题思路

  反悔贪心。贪心策略为,在尽可能短的时间内学习最多的课,对于学习相同数目的课,需要消耗的时间尽可能的少。

  首先是 在尽可能短的时间内学最多的课 ,需要对所有可能的截止时间进行升序排序,对于截止时间一样的课对课程时长进行升序排序。维护一个 nowTime 表示当前已经选择可能的总时长,如果 nowTime + courses[i][0] <= courses[i][1] 表示当前课程可以学习。

  然后对于 学习相同数目的课,需要消耗的时间尽可能的少 ,如果遇到的课程当前可能无法学习,但在已经选择的课程中,如果存在课程时长比当前遇到的课程时长要长的,说明选择当前课程更优,因为更长的截止时间内能学习一样的课程数量而且学习的总时间更短。那么就需要我们维护一个优先队列,把已经选择的课程中最长的课程时长置于队首,便于判断。具体见代码。

代码

class Solution {
    public int scheduleCourse(int[][] courses) {
        Arrays.sort(courses, (a, b) -> {
            if (a[1] == b[1]) return a[0] - b[0];
            else return a[1] - b[1];
        });

        int nowTime = 0, length = courses.length;
        PriorityQueue<Integer> queue = new PriorityQueue<>((a, b) -> b - a);
        for (int i = 0; i < length; i++) {
            if (nowTime + courses[i][0] <= courses[i][1]) {
                nowTime += courses[i][0];
                queue.add(courses[i][0]);
            } else if (!queue.isEmpty() && courses[i][0] < queue.peek()) {
                nowTime -= queue.poll();
                nowTime += courses[i][0];
                queue.add(courses[i][0]);
            }
        }
        return queue.size();
    }
}

你可能感兴趣的:(Leetcode,数据结构-优先队列,贪心,leetcode,贪心算法,算法)