题目地址: 链接
思路: 核心思路:判断图是否有环。
递归:使用数组构建课程的邻接表,如果有环,遍历时一定会陷入死循环。期间利用 vited 判断当前访问节点的状态(是否重复访问,访问完毕,未访问)。
- 如果遇到 「未访问」 节点(vited[i] == 0),进入递归;
- 如果遇到 「正在访问」 节点(vited[i] == 1),有环!返回 false;
- 如果遇到「已访问完毕」节点(vited[i] == 2),可复用结果,返回 true;
js
/**
* @param {number} numCourses
* @param {number[][]} prerequisites
* @return {boolean}
*/
var canFinish = function(numCourses, prerequisites) {
let adj = Array.from({length: numCourses}, () => new Array());
for(const [course, precourse] of prerequisites)
adj[course].push(precourse);
const vited = new Array(numCourses).fill(0);
const dfs = (i) => {
// 利用缓存,复用
if(vited[i] == 1) return false;
if(vited[i] == 2) return true;
vited[i] = 1; // 正在访问
let curPreCourse = adj[i];
let ans = true;
for(let num of curPreCourse) {
ans = dfs(num, vited);
if(!ans) return ans;
}
vited[i] = 2; // 访问结束,可以复用
return ans;
}
for(let i = 0; i < numCourses; i ++) {
if(!dfs(i)) return false;
}
return true;
};