题目:
There are a total of n courses you have to take, labeled from 0
to n-1
.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]
Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?
Example 1:
Input: 2, [[1,0]] Output: true Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
Example 2:
Input: 2, [[1,0],[0,1]] Output: false Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.
分析:
给定n门课程和他们之间的先修关系,例如[1, 0]就表示修1这门课程要先修完0,判断能否学完所有的课程。
很明显,如果课程中存在循环,就不能完成全部课程。记录每门课程之间的先后顺序,用map存储起来。遍历所有的课程,使用visit数组用来记录每门课程的访问状态,1表示正在访问,2表示已经访问过,访问课程后,在遍历这门课的后续课程,递归执行,如果出现访问的课程状态为1,也就是正在访问,那么表示图中存在环,返回false即可。
程序:
C++
class Solution { public: bool canFinish(int numCourses, vector<vector<int>>& prerequisites) { courses = vector<vector<int>> (numCourses); for(auto a:prerequisites){ courses[a[1]].push_back(a[0]); } vector<int> visit(numCourses); for(int i = 0; i < numCourses; ++i) if(dfs(i, visit)) return false; return true; } private: bool dfs(int curr, vector<int>& visit){ if(visit[curr] == 1) return true; if(visit[curr] == 2) return false; visit[curr] = 1; for(auto i:courses[curr]) if(dfs(i, visit)) return true; visit[curr] = 2; return false; } vector<vector<int>> courses; };
Java
class Solution { public boolean canFinish(int numCourses, int[][] prerequisites) { for(int[] arr:prerequisites){ List<Integer> list = courses.getOrDefault(arr[1], new ArrayList<>()); list.add(arr[0]); courses.put(arr[1], list); } int[] visit = new int[numCourses]; for(int i = 0; i < numCourses; ++i){ if(dfs(i, visit)) return false; } return true; } private boolean dfs(int curr, int[] visit){ if(visit[curr] == 1) return true; if(visit[curr] == 2) return false; visit[curr] = 1; List<Integer> list = courses.get(curr); if(list != null){ for(int i:list){ if(dfs(i, visit)) return true; } } visit[curr] = 2; return false; } private Map<Integer, List<Integer>> courses = new HashMap<>(); }