【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 }
解题关键:
图的拓扑

浙公网安备 33010602011771号