标签:
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.
The hint provided by leetcode is:
Hints:
My solution is vis DFS: (using HashSet)
1 public class Solution { 2 public boolean canFinish(int numCourses, int[][] prerequisites) { 3 if (prerequisites.length==0 || prerequisites[0].length==0) return true; 4 5 List<Set> posts = new ArrayList<Set>(); 6 for (int i = 0; i < numCourses; i++) { 7 posts.add(new HashSet<Integer>()); 8 } 9 10 // fill the adjacency list 11 for (int i = 0; i < prerequisites.length; i++) { 12 posts.get(prerequisites[i][1]).add(prerequisites[i][0]); 13 } 14 15 int[] visited = new int[numCourses]; 16 for (int i=0; i<numCourses; i++) { 17 if (!canFinishDfs(i, posts, visited)) return false; 18 } 19 return true; 20 } 21 22 public boolean canFinishDfs(int start, List<Set> posts, int[] visited) { 23 if(visited[start]==-1) 24 return false; 25 if(visited[start]==1) 26 return true; 27 28 visited[start] = -1; 29 30 Set<Integer> neighbors = posts.get(start); 31 Iterator<Integer> iter = neighbors.iterator(); 32 while(iter.hasNext()) { 33 int neibor = iter.next(); 34 if(!canFinishDfs(neibor, posts, visited)) 35 return false; 36 } 37 38 visited[start] = 1; 39 40 return true; 41 } 42 }
Another DFS solution using HashMap:
1 public boolean canFinish(int numCourses, int[][] prerequisites) { 2 if(prerequisites == null){ 3 throw new IllegalArgumentException("illegal prerequisites array"); 4 } 5 6 int len = prerequisites.length; 7 8 if(numCourses == 0 || len == 0){ 9 return true; 10 } 11 12 //track visited courses 13 int[] visit = new int[numCourses]; 14 15 // use the map to store what courses depend on a course 16 HashMap<Integer,ArrayList<Integer>> map = new HashMap<Integer,ArrayList<Integer>>(); 17 for(int[] a: prerequisites){ 18 if(map.containsKey(a[1])){ 19 map.get(a[1]).add(a[0]); 20 }else{ 21 ArrayList<Integer> l = new ArrayList<Integer>(); 22 l.add(a[0]); 23 map.put(a[1], l); 24 } 25 } 26 27 for(int i=0; i<numCourses; i++){ 28 if(!canFinishDFS(map, visit, i)) 29 return false; 30 } 31 32 return true; 33 } 34 35 private boolean canFinishDFS(HashMap<Integer,ArrayList<Integer>> map, int[] visit, int i){ 36 if(visit[i]==-1) 37 return false; 38 if(visit[i]==1) 39 return true; 40 41 visit[i]=-1; 42 if(map.containsKey(i)){ 43 for(int j: map.get(i)){ 44 if(!canFinishDFS(map, visit, j)) 45 return false; 46 } 47 } 48 49 visit[i]=1; 50 51 return true; 52 }
BFS: (refer: http://www.programcreek.com/2014/05/leetcode-course-schedule-java/)
典型的拓扑排序。原理也很简单,在一个有向图中,每次找到一个没有前驱节点的节点(也就是入度为0的节点),然后把它指向其他节点的边都去掉,重复这个过程(BFS),直到所有节点已被找到,或者没有符合条件的节点(如果图中有环存在)。
回顾一下图的三种表示方式:边表示法(即题目中表示方法),邻接表法,邻接矩阵。用邻接表存储图比较方便寻找入度为0的节点。
1 public boolean canFinish(int numCourses, int[][] prerequisites) { 2 if(prerequisites == null){ 3 throw new IllegalArgumentException("illegal prerequisites array"); 4 } 5 6 int len = prerequisites.length; 7 8 if(numCourses == 0 || len == 0){ 9 return true; 10 } 11 12 // counter for number of prerequisites 13 int[] pCounter = new int[numCourses]; 14 for(int i=0; i<len; i++){ 15 pCounter[prerequisites[i][0]]++; 16 } 17 18 //store courses that have no prerequisites 19 LinkedList<Integer> queue = new LinkedList<Integer>(); 20 for(int i=0; i<numCourses; i++){ 21 if(pCounter[i]==0){ 22 queue.add(i); 23 } 24 } 25 26 // number of courses that have no prerequisites 27 int numNoPre = queue.size(); 28 29 while(!queue.isEmpty()){ 30 int top = queue.remove(); 31 for(int i=0; i<len; i++){ 32 // if a course‘s prerequisite can be satisfied by a course in queue 33 if(prerequisites[i][1]==top){ 34 pCounter[prerequisites[i][0]]--; 35 if(pCounter[prerequisites[i][0]]==0){ 36 numNoPre++; 37 queue.add(prerequisites[i][0]); 38 } 39 } 40 } 41 } 42 43 return numNoPre == numCourses; 44 }
标签:
原文地址:http://www.cnblogs.com/EdwardLiu/p/5050550.html