leetcode630. 課程表 III(貪心 優先佇列)
連結:https://leetcode-cn.com/problems/course-schedule-iii/
題目
這裡有 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
思路
不同於其他幾道課程表,這道題需要限制了結束時間,所以我們應該貪心選擇越早結束的課程先進行修習
所以先對課程根據結束時間進行排序
然後我們判斷當前結束課程時間下的最早結束時間
構建一個優先佇列,噹噹前點結束時間可以修習時,當前點入隊
不行時,如果當前點所需時間的小於佇列中的最大所需時間,出隊,將該點時間加入
class Solution { public: int scheduleCourse(vector<vector<int>>& courses) { int n = courses.size(); sort(courses.begin(), courses.end(), [](vector<int>&a, vector<int>&b){return a[1] < b[1]; }); priority_queue<int>q; int cnt = 0; for (int i = 0; i<n; ++i){ if (cnt + courses[i][0] <= courses[i][1]){ q.push(courses[i][0]); cnt += courses[i][0]; } else if (!q.empty() && q.top()>courses[i][0]){ cnt -= q.top() - courses[i][0]; q.pop(); q.push(courses[i][0]); } } return q.size(); } };