LeetCode 207. Course Schedule

原题链接在这里:https://leetcode.com/problems/course-schedule/description/

题目:

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.

题解:

topological sort. 每一门课就是一个vertex, 每一个preRequest就是一个edge.

求Course Schedule, 等同问题是有向图检测环. 一个DAG的Topological Order可以有大于1种.

常用的Topological Sorting算法有两种

  1. Kahn's Algorithms (wiki): BFS based, start from with vertices with 0 incoming edge,insert them into list S,at the same time we remove all their outgoing edges,after that find new vertices with 0 incoming edges and go on. 
  2. Tarjan's Algorithms (wiki): DFS based, loop through each node of the graph in an arbitrary order,initiating a depth-first search that terminates when it hits any node that has already been visited since the beginning of the topological sort or the node has no outgoing edges (i.e. a leaf node). 

Time Complexity: O(V + E). Space: O(V).

AC Java:

 1 public class Solution {
 2     public boolean canFinish(int numCourses, int[][] prerequisites) {
 3         //BFS based
 4         if(numCourses <= 0){
 5             return true;
 6         }
 7         
 8         //用List<List>建立 adjancy list
 9         List<List<Integer>> fromTo = new ArrayList<List<Integer>>();
10         for(int i = 0; i<numCourses; i++){
11             fromTo.add(new ArrayList<Integer>());
12         }
13         for(int [] edge: prerequisites){
14             fromTo.get(edge[1]).add(edge[0]);
15         }
16         
17         //计算每门课的prerequisit count
18         int [] inDegree = new int[numCourses];
19         for(int [] edge : prerequisites){
20             inDegree[edge[0]]++;
21         }
22         
23         //把prerequist count为0的课加到queue里面
24         List<Integer> res = new ArrayList<Integer>();
25         LinkedList<Integer> que = new LinkedList<Integer>();
26         for(int i = 0; i<inDegree.length; i++){
27             if(inDegree[i] == 0){
28                 que.add(i);
29             }
30         }
31         
32         //从queue里poll出来的课程 去掉他们的outdegree edge
33         while(!que.isEmpty()){
34             int source = que.poll();
35             res.add(source);
36             
37             for(int destination: fromTo.get(source)){
38                 inDegree[destination]--;
39                 //若是该点的prerequist count减一后变成0, 就加到queue中.
40                 if(inDegree[destination] == 0){
41                     que.add(destination);
42                 }
43             }
44         }
45         return res.size() == numCourses;
46     }
47 }

跟上Course Schedule IICourse Schedule IIIAlien DictionaryParallel Courses.

reference: http://www.cnblogs.com/yrbbest/p/4493547.html

posted @ 2015-10-10 12:17  Dylan_Java_NYC  阅读(774)  评论(0编辑  收藏  举报