210. 课程表 II
dfs
实现
实际上就是在环检测算法的基础上,加入了一个后续遍历,并且对后续遍历的结果做了一个翻转,通过这种方式就可以保证一门课程的所有前置课程一定先于该课程被修读。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| public class FindOrderByDFS_210 { private boolean[] visited; private boolean[] onPath; private boolean hasCycle; public int[] findOrder(int numCourses, int[][] prerequisites) { visited = new boolean[numCourses]; onPath = new boolean[numCourses];
List<List<Integer>> graph = new ArrayList<>(); for (int i = 0; i < numCourses; i++) { graph.add(new ArrayList<>()); } for (int i = 0; i < prerequisites.length; i++) { graph.get(prerequisites[i][1]).add(prerequisites[i][0]); }
List<Integer> postOrder = new ArrayList<>(); for (int i = 0; i < numCourses; i++) { if (!visited[i]) { dfs(graph, i, postOrder); } } Collections.reverse(postOrder); int[] result = new int[0]; if (!hasCycle) { result = postOrder.stream().mapToInt(Integer::intValue).toArray(); } return result; }
private void dfs(List<List<Integer>> graph, int node, List<Integer> postOrder) { if (onPath[node]) { hasCycle = true; return; } if (visited[node] || hasCycle) { return; } visited[node] = true; onPath[node] = true; for (Integer nextNode : graph.get(node)) { dfs(graph, nextNode, postOrder); if (hasCycle) { return; } } postOrder.add(node); onPath[node] = false; } }
|
bfs
实现
总的思路就是利用队列来保存下一轮要访问的节点,用入度数组来控制每一轮哪些节点应该入队——当入度为零,即当前节点的所有先修课都修读完毕之后,才可以修读这门课,这个访问的顺序就已经是一个拓扑排序的结果了,只需要按顺序把这些访问节点记录起来即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| public class FindOrderByBFS_210 { public int[] findOrder(int numCourses, int[][] prerequisites) { int[] inDegree = new int[numCourses]; List<List<Integer>> graph = new ArrayList<>(); for (int i = 0; i < numCourses; i++) { graph.add(new ArrayList<>()); }
for (int[] prerequisite : prerequisites) { int from = prerequisite[1]; int to = prerequisite[0];
graph.get(from).add(to); inDegree[to]++; }
Queue<Integer> que = new LinkedList<>(); for (int i = 0; i < numCourses; i++) { if (inDegree[i] == 0) { que.offer(i); } }
int count = 0; int[] order = new int[numCourses]; while (!que.isEmpty()) { int course = que.poll(); order[count] = course; count++; for (Integer nextCourse : graph.get(course)) { inDegree[nextCourse]--; if (inDegree[nextCourse] == 0) { que.add(nextCourse); } } }
if (count == numCourses) { return order; } else { return new int[0]; } } }
|