Course Schedule

LeetCode Q 207 - Course Schedule

There are a total of n courses you have to take, labeled from 0 to n-1.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

Example 1:
Input: 2, [[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: 2, [[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.

Note:

  • The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is .
  • You may assume that there are no duplicate edges in the input prerequisites.

Solution

Solution 1 : BFS

Code:

public boolean canFinish(int numCourses, int[][] reqs) {
	if (numCourses <= 0 || reqs == null || reqs.length == 0) 
		return true;

	// build the graph and order array
	Map<Integer, Set<Integer>> graph = new HashMap<>();
	int[] order = new int[numCourses];

	for (int i = 0; i < numCourses; i++)
		graph.put(i, new HashSet<>());
	for (int[] req: reqs) {
		graph.get(req[1]).add(req[0]);
		order[req[0]]++;
	}

	Queue<Integer> que = new LinkedList<>();
	for (int i = 0; i < numCourses; i++) {
		if (order[i] == 0) que.offer(numCourses);
	}

	int count = 0;
	while (!que.isEmpty()) {
		int curr = que.poll();
		count++;
		for (int next: graph.get(curr)) {
			order[next]--;
			if (order[next] == 0)	
				que.offer(next);
		}
	}
	
	return count == numCourses;
}

Solution 2 : DFS

Tip:
Use an int[] status to represent the status of the current node.
It has 3 potential values, i.e.
0: unvisited; 1: visiting; 2: visited.

Code:

public boolean canFinish(int numCourses, int[][] reqs) {
	if (numCourses <= 0 || reqs == null || reqs.length == 0) 
		return true;

	// build the graph 
	Map<Integer, Set<Integer>> graph = new HashMap<>();
	for (int i = 0; i < numCourses; i++)
		graph.put(i, new HashSet<>());
	for (int[] req: reqs) 
		graph.get(req[1]).add(req[0]);

	int[] status = new int[numCourses];

	for (int i = 0; i < numCourses; i++) {
		if (status[i] == 2) continue;
		if (hasCycle(graph, i, status))
			return false;
	}

	return true;
}

private boolean hasCycle(Map<Integer, Set<Integer>> graph, int course, int[] status) {
	if (status[course] == 1) return true;

	status[course] = 1;
	for (int next: graph.get(course)) {
		if (status[i] == 2) continue;
		if (hasCycle(graph, next, status))
			return true;
	}

	status[course] = 2;

	return false;
}

   Reprint policy


《Course Schedule》 by Tong Shi is licensed under a Creative Commons Attribution 4.0 International License
  TOC