# Week 6 Session 1 Solutions ## [Course Schedule II](https://leetcode.com/problems/course-schedule-ii/) ``` from collections import defaultdict class Solution: UNVISITED = 0 VISITING = 1 VISITED = 2 def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]: graph = self.buildGraph(prerequisites) state = [Solution.UNVISITED] * numCourses ordering = [] for course in range(numCourses): if state[course] == Solution.UNVISITED: isPossible = self.dfs(course, graph, state, ordering) if not isPossible: return [] return reversed(ordering) def dfs(self, course, graph, state, ordering): state[course] = Solution.VISITING for neighbor in graph[course]: if state[neighbor] == Solution.UNVISITED: isPossible = self.dfs(neighbor, graph, state, ordering) if not isPossible: return False elif state[neighbor] == Solution.VISITING: return False state[course] = Solution.VISITED ordering.append(course) return True def buildGraph(self, prerequisites): graph = defaultdict(set) for (course, prerequisite) in prerequisites: graph[prerequisite].add(course) return graph ``` ## [Find Eventual Safe States](https://leetcode.com/problems/find-eventual-safe-states) ``` class Solution: UNVISITED = 0 VISITING = 1 SAFE = 3 UNSAFE = 4 def eventualSafeNodes(self, graph: List[List[int]]) -> List[int]: numNodes = len(graph) state = [Solution.UNVISITED] * numNodes for node in range(numNodes): if state[node] == Solution.UNVISITED: self.dfs(graph, node, state) safeNodes = [] for (i, nodeState) in enumerate(state): if nodeState == Solution.SAFE: safeNodes.append(i) return safeNodes def dfs(self, graph, currNode, state): if state[currNode] == Solution.SAFE: return True if state[currNode] == Solution.VISITING or state[currNode] == Solution.UNSAFE: return False state[currNode] = Solution.VISITING isSafe = True for neighbor in graph[currNode]: isSafe &= self.dfs(graph, neighbor, state) if not isSafe: break state[currNode] = Solution.SAFE if isSafe else Solution.UNSAFE return isSafe ```