1. 程式人生 > 其它 >leetcode630. 課程表 III(貪心 優先佇列)

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();
	}
};