Solving Leetcode Interviews in Seconds with AI: Parallel Courses III
Introduction
In this blog post, we will explore how to solve the LeetCode problem "2050" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
You are given an integer n, which indicates that there are n courses labeled from 1 to n. You are also given a 2D integer array relations where relations[j] = [prevCoursej, nextCoursej] denotes that course prevCoursej has to be completed before course nextCoursej (prerequisite relationship). Furthermore, you are given a 0-indexed integer array time where time[i] denotes how many months it takes to complete the (i+1)th course. You must find the minimum number of months needed to complete all the courses following these rules: You may start taking a course at any time if the prerequisites are met. Any number of courses can be taken at the same time. Return the minimum number of months needed to complete all the courses. Note: The test cases are generated such that it is possible to complete every course (i.e., the graph is a directed acyclic graph). Example 1: Input: n = 3, relations = [[1,3],[2,3]], time = [3,2,5] Output: 8 Explanation: The figure above represents the given graph and the time required to complete each course. We start course 1 and course 2 simultaneously at month 0. Course 1 takes 3 months and course 2 takes 2 months to complete respectively. Thus, the earliest time we can start course 3 is at month 3, and the total time required is 3 + 5 = 8 months. Example 2: Input: n = 5, relations = [[1,5],[2,5],[3,5],[3,4],[4,5]], time = [1,2,3,4,5] Output: 12 Explanation: The figure above represents the given graph and the time required to complete each course. You can start courses 1, 2, and 3 at month 0. You can complete them after 1, 2, and 3 months respectively. Course 4 can be taken only after course 3 is completed, i.e., after 3 months. It is completed after 3 + 4 = 7 months. Course 5 can be taken only after courses 1, 2, 3, and 4 have been completed, i.e., after max(1,2,3,7) = 7 months. Thus, the minimum time needed to complete all the courses is 7 + 5 = 12 months. Constraints: 1 <= n <= 5 104 0 <= relations.length <= min(n (n - 1) / 2, 5 * 104) relations[j].length == 2 1 <= prevCoursej, nextCoursej <= n prevCoursej != nextCoursej All the pairs [prevCoursej, nextCoursej] are unique. time.length == n 1 <= time[i] <= 104 The given graph is a directed acyclic graph.
Explanation
Here's the solution to the problem, with explanations and the code in Python:
High-Level Approach:
- Topological Sort: The problem involves dependencies between courses, making it a natural fit for topological sorting. We can use Kahn's algorithm (BFS-based) for topological sort to process courses in an order that respects prerequisites.
- Earliest Start Time: While performing the topological sort, we maintain an array
earliest_startto track the earliest possible time each course can start. This will be the maximum completion time of all its prerequisites. Total Time: The minimum time to complete all courses is the maximum of
earliest_start[i] + time[i]for all coursesi.Runtime Complexity: O(V + E), where V is the number of courses (n) and E is the number of relations. Storage Complexity: O(V + E)
Code
from collections import defaultdict, deque
def minimumTime(n: int, relations: list[list[int]], time: list[int]) -> int:
"""
Calculates the minimum time needed to complete all courses.
Args:
n: The number of courses.
relations: A list of prerequisite relationships (prevCourse, nextCourse).
time: A list of time required for each course.
Returns:
The minimum time needed to complete all courses.
"""
graph = defaultdict(list)
in_degree = [0] * n
earliest_start = [0] * n
for prev_course, next_course in relations:
graph[prev_course - 1].append(next_course - 1)
in_degree[next_course - 1] += 1
queue = deque()
for i in range(n):
if in_degree[i] == 0:
queue.append(i)
while queue:
course = queue.popleft()
for next_course in graph[course]:
earliest_start[next_course] = max(earliest_start[next_course], earliest_start[course] + time[course])
in_degree[next_course] -= 1
if in_degree[next_course] == 0:
queue.append(next_course)
max_time = 0
for i in range(n):
max_time = max(max_time, earliest_start[i] + time[i])
return max_time