在一个有向图中,每次找到一个没有前驱节点的节点(也就是入度为0的节点),然后把它指向其他节点的边都去掉,重复这个过程(BFS),直到所有节点已被找到,或者没有符合条件的节点(如果图中有环存在)。
/* 思路就是平时学习的过程,每次都学习一个最先导课程(特征就是该课程没有先导课程),学完所有课程后就成功 如果在某次遍历是发现所有课程都有先导课程,就失败退出。 用一个数组记录每个课程都有几个先导课程,用多个hashset(BFS的数据记录结构)记录该课程的后续课程有哪些, 每次学一个课程,就把该课程的后续课程的先导课程-1 */ public boolean canFinish(int numCourses, int[][] prerequisites){ List<Set> list = new ArrayList<>(); for (int i = 0; i < numCourses; i++) { list.add(new HashSet<Integer>()); } //记录每个课程的后续课程 for (int i = 0; i < prerequisites.length; i++) { list.get(prerequisites[i][1]).add(prerequisites[i][0]); } int[] pre = new int[numCourses]; //记录每个课程的先导课程个数 for (int i = 0; i < numCourses; i++) { Set set = list.get(i); Iterator<Integer> iter = set.iterator(); while (iter.hasNext()) pre[iter.next()]++; } //下面开始BFS for (int i = 0; i < numCourses; i++) { int j = 0; //寻找最先导课程 for (; j < numCourses; j++) { if (pre[j]==0) break; } //无先导课程,有环 if (j==numCourses) return false; //已经学习过的置-1 pre[j]=-1; // bfs过程,把后续课程的 Set set = list.get(j); Iterator<Integer> iter = set.iterator(); while (iter.hasNext()) pre[iter.next()]--; } return true; }