207. Course Schedule

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?
For example:
2, [[1,0]]
There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
2, [[1,0],[0,1]]
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.

这个问题等价于在一个有向图中寻找有没有圈。
我们找到没有入度的节点,删掉它,在其邻接点的入度中将其去掉,再找下一个没有入度的点。
样下来如果没有圈所有的点都会被去掉。如果有圈就剩下了这个圈,他们的入度永远不可能互相去掉。

var canFinish = function(numCourses, prerequisites) {
    var num = prerequisites.length;
    if (num===0) return true;
    var map = {};
    var count = 0;
    //遍历数组,记录下每个节点的入度和出度
    for (let i = 0;i < num;i++) {
        if (map[prerequisites[i][0]] === undefined) {
            map[prerequisites[i][0]] = [new Set(),new Set()];
            count++;
        }
        if (map[prerequisites[i][1]] === undefined) {
            map[prerequisites[i][1]] = [new Set(),new Set()];
            count++;
        }
        //入度
        map[prerequisites[i][0]][0].add(prerequisites[i][1]);
        //出度
        map[prerequisites[i][1]][1].add(prerequisites[i][0]);
    }
    var lastRemove = [];
    var removeing = [];
    //找到所有没有入度的点
    for (let node in map) {
        if (map[node][0].size===0) 
            lastRemove.push(parseInt(node));
    }
    while (count !== 0&&lastRemove.length !== 0) {
        var numL = lastRemove.length;
        count -= numL;
        for (let i = 0; i < numL;i++) {
            //要删除的节点没有入度,遍历出度数组,找到邻接点们
            //从他们的入度中删掉这个点,新的无入度的点将从这里产生
            for (var j of map[lastRemove[i]][1]) {
                map[j][0].delete(lastRemove[i]);
                if (map[j][0].size === 0) removeing.push(j);
            }
        }
        lastRemove = removeing;
        removeing = [];
    }
    //如果没有删除所有的点,就说明有圈
    if (count !== 0)
        return false;
    return true;
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容