There are n different online courses numbered from 1 to n. You are given an array courses where courses[i] = [durationi, lastDayi] indicate that the ith course should be taken continuously for durationi days and must be finished before or on lastDayi.
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 <= 1041 <= durationi, lastDayi <= 104When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force way to solve this scheduling problem is to try every possible combination of courses. We want to find the largest number of courses we can take without exceeding any course deadlines. This means exploring all subsets of courses.
Here's how the algorithm would work step-by-step:
def course_schedule_brute_force(courses):
maximum_courses = 0
number_of_courses = len(courses)
# Iterate through all possible subsets of courses.
for i in range(1 << number_of_courses):
current_schedule = []
for j in range(number_of_courses):
if (i >> j) & 1:
current_schedule.append(courses[j])
# Sort the courses by their deadlines for evaluation
current_schedule.sort(key=lambda course: course[1])
current_time = 0
can_complete = True
# Check if the current schedule is valid.
for course_duration, course_deadline in current_schedule:
current_time += course_duration
# If the current schedule is invalid, break
if current_time > course_deadline:
can_complete = False
break
# Update the maximum number of courses if applicable.
if can_complete:
number_of_courses_in_schedule = len(current_schedule)
#If this schedule is valid, update maximum_courses
maximum_courses = max(maximum_courses, number_of_courses_in_schedule)
return maximum_coursesThe problem asks us to take as many courses as possible, given that each course has a duration and a deadline. The key idea is to prioritize courses that finish earlier, but we can also 'swap' courses if a later course is shorter and lets us take more courses overall.
Here's how the algorithm would work step-by-step:
import heapq
def course_schedule_three(courses):
courses.sort(key=lambda course: course[1])
current_schedule = []
total_duration = 0
for duration, last_day in courses:
total_duration += duration
heapq.heappush(current_schedule, -duration)
# If total time exceeds the deadline, remove the longest course.
if total_duration > last_day:
total_duration += heapq.heappop(current_schedule)
# The number of courses in the schedule is the answer.
return len(current_schedule)| Case | How to Handle |
|---|---|
| Empty courses array | Return 0 immediately as no courses can be taken. |
| Courses with duration 0 | Treat courses with duration 0 like any other course, since they contribute to the course deadline and should be considered if they allow taking more courses. |
| Courses with deadline 0 | These courses can only be taken if there is available time before needing to take any other course. |
| Large number of courses exceeding memory limits | The priority queue (heap) could potentially grow large; consider using an iterative approach and appropriate data structures to manage memory efficiently. |
| Courses sorted in decreasing order of deadline | The greedy approach of sorting by deadline still works, ensuring earlier deadlines are prioritized, while the heap handles later deadlines. |
| Courses with very large durations or deadlines (potential integer overflow) | Use long data types for durations and deadlines to prevent integer overflow during calculations. |
| No course can be taken within its deadline | The algorithm should correctly return 0 as it won't be able to fit any course into the schedule. |
| All courses have the same deadline | The algorithm should still correctly determine the maximum number of courses possible considering their durations, filling as much as possible up to that single deadline. |