LeetCode-in-Go

207. Course Schedule

Medium

There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai.

Return true if you can finish all courses. Otherwise, return false.

Example 1:

Input: numCourses = 2, prerequisites = [[1,0]]

Output: true

Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

Example 2:

Input: numCourses = 2, prerequisites = [[1,0],[0,1]]

Output: false

Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

Constraints:

Solution

type State int

const (
	Unvisited State = iota
	Visiting
	Visited
)

func canFinish(numCourses int, prerequisites [][]int) bool {
	visited := make([]State, numCourses)
	graph := make([][]int, numCourses)
	for _, dep := range prerequisites {
		graph[dep[1]] = append(graph[dep[1]], dep[0])
	}
	for i := 0; i < numCourses; i++ {
		if visited[i] == Unvisited {
			if !dfs(i, visited, graph) {
				return false
			}
		}
	}
	return true
}

func dfs(start int, visited []State, graph [][]int) bool {
	if visited[start] == Visiting {
		return false
	}
	if visited[start] == Visited {
		return true
	}
	visited[start] = Visiting
	for _, next := range graph[start] {
		if !dfs(next, visited, graph) {
			return false
		}
	}
	visited[start] = Visited
	return true
}