题目的本质就是判断有向图中是否存在环路,可以选择用 DFS 搜索来解决。但是需要注意的是,在对每一个可能的起点(每一门课)进行搜索完成之后,需要设置标记位防止在后续的搜索轮次中重复搜索浪费时间。
代码如下:
const canFinish = (numCourses, prerequisites) => {
/**
* 0 - not visited
* 1 - visited in current round, not certain if it is safe
* -1 - visited in rounds before and safe
*/
const flags = Array(numCourses).fill(0);
// create the graph
const adjacency = Array(numCourses).fill(null).map(() => ([]));
prerequisites.forEach(pair => {
adjacency[pair[1]].push(pair[0]);
});
const dfs = id => {
// if this node is visited before in this round,
// there is a circle in the graph, return false
if (flags[id] === 1) return false;
// if this node is proved to be safe in previous rounds,
// no need to check again
if (flags[id] === -1) return true;
// change the flag for this course to be visited in this round
flags[id] = 1;
// continue the search for all nodes are adjacent to itself
for (const nextId of adjacency[id]) {
// if it goes bad then return false early
if (!dfs(nextId)) {
return false;
}
}
// this round turns to be ok, set the flag to -1
flags[id] = -1;
return true;
}
for (let i = 0; i < numCourses; i++) {
// start the dfs for every possible course
if (!dfs(i)) {
return false;
}
}
return true;
};