Course Schedule in Python

The Course Schedule problem asks whether we can complete all courses given their prerequisites. This is essentially a cycle detection problem in a directed graph where courses are nodes and prerequisites are edges.

Problem Understanding

Given a number of courses and prerequisite pairs, we need to determine if it's possible to finish all courses. For example, if we have 2 courses and prerequisites = [[1, 0]], it means to take course 1, we must first complete course 0. This is possible, so we return True.

Algorithm Approach

We solve this using Depth-First Search (DFS) with cycle detection ?

  • Build an adjacency list from prerequisites
  • Use a visited array with three states: 0 (unvisited), -1 (visiting), 1 (visited)
  • If we encounter a node with state -1 during DFS, we found a cycle
  • If no cycles exist, all courses can be completed

Implementation

class Solution:
    def canFinish(self, numCourses, prerequisites):
        if len(prerequisites) == 0:
            return True
        
        visited = [0 for i in range(numCourses)]
        adj_list = self.make_graph(prerequisites)
        
        for i in range(numCourses):
            if not visited[i]:
                if not self.cycle(adj_list, visited, i):
                    return False
        return True
    
    def cycle(self, adj_list, visited, current_node=0):
        if visited[current_node] == -1:  # Currently visiting - cycle found
            return False
        if visited[current_node] == 1:   # Already visited
            return True
        
        visited[current_node] = -1  # Mark as visiting
        
        if current_node in adj_list:
            for neighbor in adj_list[current_node]:
                if not self.cycle(adj_list, visited, neighbor):
                    return False
        
        visited[current_node] = 1  # Mark as visited
        return True
    
    def make_graph(self, prerequisites):
        adj_list = {}
        for course, prereq in prerequisites:
            if prereq in adj_list:
                adj_list[prereq].append(course)
            else:
                adj_list[prereq] = [course]
        return adj_list

# Test the solution
solution = Solution()
print(solution.canFinish(2, [[1, 0]]))
print(solution.canFinish(2, [[1, 0], [0, 1]]))
True
False

How It Works

The algorithm uses three states for each node ?

  • 0 (White): Unvisited node
  • -1 (Gray): Currently being processed (visiting)
  • 1 (Black): Completely processed (visited)

When we encounter a gray node during DFS traversal, it indicates a back edge, which means a cycle exists in the graph.

Example Walkthrough

For prerequisites = [[1, 0], [0, 1]] ?

  1. Build graph: {0: [1], 1: [0]}
  2. Start DFS from node 0, mark it as gray (-1)
  3. Visit neighbor 1, mark it as gray (-1)
  4. From node 1, try to visit neighbor 0
  5. Node 0 is already gray, so cycle detected
  6. Return False

Time and Space Complexity

  • Time Complexity: O(V + E) where V is number of courses and E is number of prerequisites
  • Space Complexity: O(V + E) for the adjacency list and visited array

Conclusion

The course schedule problem is solved using DFS-based cycle detection. If the prerequisite graph contains a cycle, it's impossible to complete all courses. Otherwise, all courses can be finished.

Updated on: 2026-03-25T08:18:30+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements