[Leetcode] 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?

For example:

2, [[1,0]]

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

2, [[1,0],[0,1]]

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 represented.

click to show more hints.

Hints:
    1. This problem is equivalent to finding if a cycle exists in a directed graph. If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses.
    2. Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining the basic concepts of Topological Sort.
    3. Topological sort could also be done via BFS.

 

------------------------------------------------------------------------------

BFS: 先扫一遍数组,找到没有prerequisites的课程,加入到queue里 (没有prerequisites的课程就是我们可以完成的课程)。

在来对queue里的数进行处理,知道找到所有可以完成的课程。 比较其与numCourses的大小。

 1 public class Solution {
 2     // BFS VERSION
 3     public boolean canFinish(int numCourses, int[][] prerequisites) {
 4         int[] pCounter = new int[numCourses];
 5         for(int[] temp: prerequisites) {
 6             pCounter[temp[0]]++;
 7         }
 8         Queue<Integer> noPre = new LinkedList<Integer>();
 9         for(int i = 0; i < pCounter.length; ++i) {
10             if(pCounter[i] == 0)
11                 noPre.offer(i);
12         }
13         int res = noPre.size();
14         while(!noPre.isEmpty()) {
15             int cur = noPre.poll();
16             for(int[] temp: prerequisites) {
17                 if(temp[1] == cur) {
18                     pCounter[temp[0]]--;
19                     if(pCounter[temp[0]] == 0) {
20                         noPre.add(temp[0]);
21                         res++;
22                     }
23                 }
24             }
25         }
26         return res == numCourses;
27     }
28 }

DFS:

与BFS去找没有pre-node的节点方法不同,DFS是利用:这个点作为prerequisite,我接下来可以选择哪些node来处理的。

在这里,我们需要用一个boolean的数组来判断这个node我们之前有没有访问过,如果访问过了,说明有cycle。

 1 // DFS VERSION
 2     public boolean canFinish(int numCourses, int[][] prerequisites) {
 3         ArrayList[] nodes = new ArrayList[numCourses];
 4         for(int i = 0; i < numCourses; ++i) {
 5             nodes[i] = new ArrayList<Integer>();
 6         }
 7         for(int[] temp: prerequisites) {
 8             nodes[temp[1]].add(temp[0]);
 9         }
10         boolean[] visited = new boolean[numCourses];
11         for(int i = 0; i < numCourses; ++i) {
12             if(!canFinish(nodes, visited ,i))
13                 return false;
14         }
15         return true;
16     }
17     public boolean canFinish(ArrayList[] nodes, boolean[] visited, int curIndex) {
18         if(visited[curIndex])
19             return false;
20         visited[curIndex] = true;
21         ArrayList<Integer> curNeighbors = nodes[curIndex];
22         for(int next: curNeighbors) {
23             if(!canFinish(nodes, visited, next))
24                 return false;
25         }
26         visited[curIndex] = false;
27         return true;
28     }

 

posted @ 2015-10-22 09:39  Phoebe815  阅读(164)  评论(0编辑  收藏  举报