Description
There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai.
For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1.
Return true if you can finish all courses. Otherwise, return false.
Example
Example 1:
Input: numCourses = 2, prerequisites = [[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: numCourses = 2, prerequisites = [[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.
Constraints:
1 <= numCourses <= 1 0 5 10^5 105
0 <= prerequisites.length <= 5000
prerequisites[i].length == 2
0 <= ai, bi < numCourses
All the pairs prerequisites[i] are unique.
思路
这道题其实就是判断图中有没有环
所以可以通过dfs来做
有一个小trick是需要做一下剪枝(不然会导致TLE),就是我引入了一个“checked”全局变量,用来存储哪些节点已经判断完成了,这样每次的循环只要从checked开始就行,因为一旦到了checked,后面一定不存在环,可以略过不去判断
代码
class Solution {
int[][] connectCourses;
int[] visited;
int checked = 0;
public boolean haveCircle(int start){
for (int j = checked; j < connectCourses.length; j++){
if (connectCourses[start][j] == 1){
if (visited[j] == 1)
return true;
visited[j] = 1;
if (haveCircle(j))
return true;
visited[j] = 0;
}
}
return false;
}
public boolean canFinish(int numCourses, int[][] prerequisites) {
connectCourses = new int[numCourses][numCourses];
visited = new int[numCourses];
// 构建邻接矩阵
for (int i = 0; i < prerequisites.length; i++){
connectCourses[prerequisites[i][0]][prerequisites[i][1]] = 1;
}
// 找有没有环存在
for (int i = 0; i < numCourses; i++){
if (haveCircle(i))
return false;
checked++;
}
return true;
}
}