拓扑排序的经典应用。review时发现自己搞反了课程直接的依赖关系,但却真切地被Accept,
图上画了画,发现搞反后若输出排序结果就是和原来相反,但不影响本题的正确性。
网上搜了搜逆拓扑,发现其是有可用之处的,参见下面这篇博文:
http://blog.csdn.net/guodongxiaren/article/details/37988833
另一篇博文提出拓扑排序是所有节点dfs的逆后序,也就是每个节点任务完成的时间的逆序排序 ,这个洞见也挺有意思的 https://m.oschina.net/blog/419291
public class Solution { // method 2: 二维数组表示有向图 public boolean canFinish2(int numCourses, int[][] prerequisites) { if (prerequisites == null || prerequisites.length == 0 || prerequisites[0].length == 0) return true; // build graph ArrayList<HashSet<Integer>> graph = new ArrayList<HashSet<Integer>>(numCourses); int[] indegree = new int[numCourses]; for (int i = 0; i < numCourses; i++) { graph.add(new HashSet<Integer>()); } int m = prerequisites.length; for (int i = 0; i < m; i++) { if (graph.get(prerequisites[i][1]).add(prerequisites[i][0])) indegree[prerequisites[i][0]]++; } LinkedList<Integer> queue = new LinkedList<Integer>(); for (int i = 0; i < numCourses; i++) { if (indegree[i] == 0) queue.offer(i); } int counter = 0; while (!queue.isEmpty()) { counter++; int curr = queue.poll(); for (int w : graph.get(curr)) { if (--indegree[w] == 0) queue.offer(w); } } return counter == numCourses; } // method 1 class Vertex { int value; int indegree; HashSet<Vertex> adjacent; public Vertex(int val) { this.value = val; indegree = 0; adjacent = new HashSet<Vertex>(); } } public boolean canFinish(int numCourses, int[][] prerequisites) { if (prerequisites == null || prerequisites.length == 0 || prerequisites[0].length == 0) return true; HashMap<Integer, Vertex> graph = buildGraph(numCourses, prerequisites); LinkedList<Vertex> queue = new LinkedList<Vertex>(); for(Vertex node : graph.values()) { if (node.indegree == 0) queue.offer(node); } int counter = 0; while (!queue.isEmpty()) { Vertex node = queue.poll(); counter++; for (Vertex w : node.adjacent) { w.indegree--; if (w.indegree == 0) queue.offer(w); } } return counter == graph.size(); } private HashMap<Integer, Vertex> buildGraph(int numCourses, int[][] prerequisites) { HashMap<Integer, Vertex> graph = new HashMap<Integer, Vertex>(); for (int i = 0; i < numCourses; i++) { graph.put(i, new Vertex(i)); } int m = prerequisites.length; for (int i = 0; i < m; i++) { if(graph.get(prerequisites[i][1]).adjacent.add(graph.get(prerequisites[i][0]))) { graph.get(prerequisites[i][0]).indegree++; } } return graph; } }