---
# System prepended metadata

title: Week 6 Session 1 Solutions

---

# 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
```