Skip to main content

Course Schedule III


Course Schedule III: There are n different online courses numbered from 1 to n. You are given an array courses where courses[i] = [duration_i, lastDay_i] indicate that the ith course should be taken continuously for duration_i days and must be finished before or on lastDay_i.

You will start on the 1st day and you cannot take two or more courses simultaneously.

Return the maximum number of courses that you can take.

Example 1:
Input: courses = [[100,200],[200,1300],[1000,1250],[2000,3200]]
Output: 3
Explanation:
There are 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.

Example 2:
Input: courses = [[1,2]]
Output: 1

Example 3:
Input: courses = [[3,2],[4,3]]
Output: 0

Constraints:
  • 1 <= courses.length <= 10^4
  • 1 <= duration_i, lastDay_i <= 10^4

Try this Problem on your own or check similar problems:

  1. Course Schedule
  2. Course Schedule II
  3. Parallel Courses III
Solution:
public int scheduleCourse(int[][] courses) {
Arrays.sort(courses, (a,b)-> a[1] - b[1]);
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
int day = 0;
for (int[] course : courses)
{
day += course[0];
pq.add(course[0]);
if (day > course[1]) day -= pq.poll();
}
return pq.size();
}

Time/Space Complexity:
  • Time Complexity: O(nlogn)
  • Space Complexity: O(n)

Explanation:

There are two core points for this algorithm:

  • We want to sort by ascending end day, since we want to take as many courses as possible, the ones ending soon are obviously our best candidates.
  • Let's say we have a course which duration when added to day (total duration of courses added) will be larger than that course end day. So how can we fit it inside the current course arrangement? First note that previous arrangement is valid (courses fit), so if we want to remove the maximum duration course, we would be able to fit the current course and still have a valid arrangement (there is also a scenario where current course is the maximum duration course, so it makes sense to just remove it from the queue).

Finally, our queue will hold the maximum number of courses we can take. The time complexity is O(nlogn) time required to traverse the array each time doing operations on the heap (logn), while we have linear space complexity since the queue can hold at most n courses. Might be hard to note but the idea of the algorithm is similar to Patience sort we implemented in Longest Increasing Subsequence as we're increasing the subsequence consisting of courses, but also keeping track of all past courses we have added so we can use that knowledge to redirect the sequence if something better comes our way (a better course selection) or in other words discard the longest course with the new course to have a longer valid sequence of courses.