这是LeetCode 630题“课程表 III”的Java解法,采用贪心算法与优先队列(最大堆),时间复杂度O(n log n),空间复杂度O(n)。

import java.util.Arrays;
import java.util.PriorityQueue;

class Solution {
    public int scheduleCourse(int[][] courses) {
        // 1. 按照课程的截止时间升序排序
        Arrays.sort(courses, (a, b) -> a[1] - b[1]);
        
        // 2. 最大堆:存储已选课程的持续时间
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
        int totalTime = 0; // 当前已选课程的总耗时
        
        for (int[] course : courses) {
            int duration = course[0];
            int lastDay = course[1];
            
            // 先假设选上当前课程
            totalTime += duration;
            maxHeap.offer(duration);
            
            // 如果总耗时超过了截止时间,则移除持续时间最长的课程(贪心:去掉最费时的课)
            if (totalTime > lastDay) {
                totalTime -= maxHeap.poll(); // 弹出最大 duration
            }
        }
        
        // 堆的大小即为最多可以修的课程数
        return maxHeap.size();
    }
}

解题思路

· 排序:优先考虑截止时间早的课程,这样可以为后续课程留出更多时间。
· 贪心选择:遍历每个课程,总是先尝试加入。如果加入后总时间超过当前课程的截止时间,则从已选课程中移除一门耗时最长的课程(因为移除耗时长的课程可以最大程度地减少总时间,且不影响已选课程的数量——只是替换了一门课)。这保证了在满足截止时间的前提下,尽可能多地选课。
· 最大堆:用优先队列维护已选课程的持续时间,方便快速获取最大值。

复杂度分析

· 时间复杂度:O(n log n),其中n为课程数量。排序需要O(n log n),每个课程入堆和出堆操作也是O(log n)。
· 空间复杂度:O(n),堆的存储空间。

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐