原题链接在这里:https://leetcode.com/problems/course-schedule-iii/description/
题目:
There are n
different online courses numbered from 1
to n
. Each course has some duration(course length) t
and closed on dth
day. A course should be taken continuously for t
days and must be finished before or on the dth
day. You will start at the 1st
day.
Given n
online courses represented by pairs (t,d)
, your task is to find the maximal number of courses that can be taken.
Example:
Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]] Output: 3 Explanation: There're totally 4 courses, but you can take 3 courses at most: First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day. Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day. Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date.
Note:
- The integer 1 <= d, t, n <= 10,000.
- You can't take two courses simultaneously.
题解:
无论课时长短,都应该先争取完成截止日期较小的课程.
下面例子中, [a, x] 代表第一堂课耗时a, 截止时间x. [b, y]代表第二堂课耗时b, 截止时间y.
有以下四种情况
1. (a+b)≤x(a+b)≤x: In this case, we can take the courses in any order. Both the courses can be taken irrespective of the order in which the courses are taken.
2. (a+b)>x(a+b)>x, a>ba>b, (a+b)≤y(a+b)≤y: In this case, as is evident from the figure, both the courses can be taken only by taking course aa before bb.
3. (a+b)>x(a+b)>x, b>ab>a, (a+b)≤y(a+b)≤y: In this case also, both the courses can be taken only by taking course aa before bb.
4. (a+b)>y(a+b)>y: In this case, irrespective of the order in which we take the courses, only one course can be taken.
上面的情况表明无论耗时长短,都应该先完成截止日期较小的课程. 所以先按照截止时间排序.
接着挨个上课, 若是遇到超时,最好的选择是drop掉之前耗时最多的课程. 这么做可以留出更大的buffer.
因为已经按照截止排序了, 新的课程截止时间y会更大, 前面的耗时加起来time比前面的截止时间x小, 所以也会比y小. 加上现在的时间去掉最大的时间time会变得更小, 也会比y小. 就不会超时了.
Time Complexity: O(nlogn). n = courses.length.
Space: O(n).
AC Java:
1 class Solution { 2 public int scheduleCourse(int[][] courses) { 3 // 先完成截止时间靠前的课程 4 Arrays.sort(courses, (a, b)->(a[1]-b[1])); 5 6 PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(Collections.reverseOrder()); 7 int time = 0; 8 for(int [] course : courses){ 9 time += course[0]; 10 maxHeap.add(course[0]); 11 if(time > course[1]){ 12 // 当时间超过截止日期 就drop掉前面耗时最多的一门课 greedy 13 // 这是此时最好的解法. 14 time -= maxHeap.poll(); 15 } 16 } 17 18 return maxHeap.size(); 19 } 20 }