207-Course Schedule
【题目】
你有n门课程需要上,几位0到n-1.
有些课程需要一些预备课程,例如:上课程0前需要先上课程1,表示为对[0,1]
假设给你所有课程和这些课程的对关系,有可能上完所有课程吗?
举例:
2 , [[1,0]]
这有2个课程需要完成,完成课程1前需要完成课程0,所以是可能的。
2 , [[1,0],[0,1]]
这有2个课程需要完成,完成课程1前需要完成课程0,完成课程0前需要完成课程1,所以是不可能的。
【分析】
1. 问题可以抽象为图的问题,就是判断图里是否存在环
2. 解决方法:(拓扑排序),求出所有点的入度,循环遍历n(n为点个数)次,每一次循环里判断是否有点的入度 为0;若所有的点的入度都不为0,return false;
反之,当前点的入度置为-1,进入下一次循环;跳出循环后,return true
【算法实现】
public class Solution { public boolean canFinish(int numCourses, int[][] prerequisites) { List<Set<Integer>> ls = new ArrayList<Set<Integer>>(); for(int i=0; i<numCourses; i++) { ls.add(new HashSet<Integer>()); } for(int i=0; i<prerequisites.length; i++) { ls.get(prerequisites[i][1]).add(prerequisites[i][0]); } int[] preNum = new int[numCourses]; for(int i=0; i<numCourses; i++) { Set<Integer> set = ls.get(i); Iterator<Integer> it = set.iterator(); while(it.hasNext()) { preNum[it.next()]++; } } for(int i=0; i<numCourses; i++) { int j; for(j=0; j<numCourses; j++) { if(preNum[j]==0) break; } if(j==numCourses) return false; preNum[j] = -1; Set<Integer> set = ls.get(j); Iterator<Integer> it = set.iterator(); while(it.hasNext()) { preNum[it.next()]--; } } return true; } }