解题思路
前置知识:拓扑排序
逐步删除入度为0的节点,直到没有入度为0的节点为止
- 如果所有节点都被删除了,说明图中没有环,课程表是可以完成的,返回
true;
- 如果还有节点没有被删除,说明图中存在环,课程表无法完成,返回
false。
参考代码
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
| class Solution {
private boolean res = false;
public boolean canFinish(int numCourses, int[][] prerequisites) { List<Integer>[] g = new ArrayList[numCourses]; Arrays.setAll(g, i -> new ArrayList<>()); for (int[] p : prerequisites) { g[p[1]].add(p[0]); }
int[] state = new int[numCourses];
for (int i = 0; i < numCourses; i ++) { if(state[i] == 0) { dfs(i, g, state); } }
return !res; }
private void dfs(int x, List<Integer>[] g, int[] state) { if(state[x] == 2) { return; } if(state[x] == 1) { res = true; return; } state[x] = 1; for(int gg : g[x]) { dfs(gg, g, state); } state[x] = 2; } }
|
邻接矩阵
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
| class Solution { public boolean canFinish(int numCourses, int[][] prerequisites) { int res = numCourses; int[] indegress = new int[numCourses]; int[][] courses = new int[numCourses][numCourses]; Queue<Integer> queue = new LinkedList<>(); for (int[] p : prerequisites) { courses[p[0]][p[1]] = 1; indegress[p[1]]++; }
for (int i = 0; i < indegress.length; i++) { if (indegress[i] == 0) { queue.add(i); } }
while (!queue.isEmpty()) { int course = queue.remove(); res--; for (int i = 0; i < numCourses; i++) { if (courses[course][i] == 1) { indegress[i]--; if (indegress[i] == 0) { queue.add(i); } }
} } return res == 0; } }
|