LeetCode-in-Net.github.io

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

using System.Collections.Generic;

public class Solution {
    private static readonly int WHITE = 0;
    private static readonly int GRAY = 1;
    private static readonly int BLACK = 2;

    public bool CanFinish(int numCourses, int[][] prerequisites) {
        List<int>[] adj = new List<int>[numCourses];
        for (int i = 0; i < numCourses; i++) {
            adj[i] = new List<int>();
        }
        foreach (int[] pre in prerequisites) {
            adj[pre[1]].Add(pre[0]);
        }
        int[] colors = new int[numCourses];
        for (int i = 0; i < numCourses; i++) {
            if (colors[i] == WHITE && adj[i].Count > 0 && HasCycle(adj, i, colors)) {
                return false;
            }
        }
        return true;
    }

    private bool HasCycle(List<int>[] adj, int node, int[] colors) {
        colors[node] = GRAY;
        foreach (int nei in adj[node]) {
            if (colors[nei] == GRAY) {
                return true;
            }
            if (colors[nei] == WHITE && HasCycle(adj, nei, colors)) {
                return true;
            }
        }
        colors[node] = BLACK;
        return false;
    }
}