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算法有两种
- 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.
- 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 II, Course Schedule III, Alien Dictionary, Parallel Courses.