算法笔记32:课程表

183 阅读1分钟

207. 课程表

题目的本质就是判断有向图中是否存在环路,可以选择用 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;
};