【LeetCode】—— 课程表

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程  bi 。

例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。

 

示例 1:

输入:numCourses = 2, prerequisites = [[1,0]]
输出:true
解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。
示例 2:

输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
输出:false
解释:总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。
 

提示:

1 <= numCourses <= 105
0 <= prerequisites.length <= 5000
prerequisites[i].length == 2
0 <= ai, bi < numCourses
prerequisites[i] 中的所有课程对 互不相同

 

 1 class Solution {
 2     // 存储每个课程的后修课程集合
 3     List<List<Integer>> edges;
 4     // 当前元素为0,没有访问过,为2,已经访问过;为1,还在访问中
 5     int[]visited;
 6     // 判断有效性
 7     boolean valid;
 8     public boolean canFinish(int numCourses, int[][] prerequisites) {
 9         // 深度优先搜索
10         // 初始化
11         edges = new ArrayList<List<Integer>>();
12         visited = new int[numCourses];
13         valid = true;
14         for (int i = 0;i<numCourses;i++){
15             edges.add(new ArrayList<>());
16         }
17         for (int i=0;i<prerequisites.length;i++){
18             // prerequisites[i][1]先修课程,prerequisites[i][0]后修课程
19             edges.get(prerequisites[i][1]).add(prerequisites[i][0]);
20         }
21 
22         for (int i=0;i<numCourses&&valid;i++){
23             if (visited[i]==0){
24                 // 没有被访问过
25                 dfs(i);
26             }
27         }
28         return valid;
29     }
30     public void dfs(int u){
31         // 访问ing
32         visited[u]=1;
33         for (int v:edges.get(u)){
34             if (visited[v]==0){
35                 dfs(v);
36                 // 深度优先搜索后会回来,判断valid
37                 if (!valid){
38                     return;
39                 }
40             }else if(visited[v]==1){
41                 // 访问ing
42                 valid=false;
43                 return;
44             }
45             // visited[v]==2是已完成
46         }
47         visited[u]=2;
48     }
49 }

 

解题关键:

图的拓扑

posted @ 2021-11-16 13:00  吾辈当奋斗-生生不息  阅读(52)  评论(0)    收藏  举报