【LeetCode】207. Course Schedule (2 solutions)

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.

Note:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.

click to show more hints.

 

解法一:每个连通分量,只要出现回路,即说明冲突了。

回路检测如下:

存在a->b,又存在b->c,那么增加边a->c

如果新增边c->a,发现已有a->c,在矩阵中表现为对称位置为true,则存在回路。

注:数组比vector速度快。

class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        bool **preG;
        preG = new bool*[numCourses];
        for(int i = 0; i < numCourses; i ++)
            preG[i] = new bool[numCourses];
        for(int i = 0; i < numCourses; i ++)
        {
            for(int j = 0; j < numCourses; j ++)
                preG[i][j] = false;
        }
        for(int i = 0; i < prerequisites.size(); i ++)
        {
            int a = prerequisites[i].first;
            int b = prerequisites[i].second;
            if(preG[b][a] == true)
                return false;
            else
            {
                preG[a][b] = true;
                for(int j = 0; j < numCourses; j ++)
                {
                    if(preG[j][a] == true)
                        preG[j][b] = true;
                }
            }
        }
        return true;
    }
};

解法二:不断删除出度为0的点,如果可以逐个删除完毕,说明可以完成拓扑序,否则说明存在回路。

class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<int> outd(numCourses, 0);
        vector<bool> del(numCourses, false);
        unordered_map<int, vector<int> > graph;
        // construct reverse neighborhood graph
        // graph is to decrease the out-degree of a set of vertices, 
        // when a certain vertice is deleted
        for(int i = 0; i < prerequisites.size(); i ++)
        {
            outd[prerequisites[i].first] ++;
            graph[prerequisites[i].second].push_back(prerequisites[i].first);
        }
        int count = 0;
        while(count < numCourses)
        {
            int i;
            for(i = 0; i < numCourses; i ++)
            {
                if(outd[i] == 0 && del[i] == false)
                    break;
            }
            if(i < numCourses)
            {
                del[i] = true;  // delete
                for(int j = 0; j < graph[i].size(); j ++)
                {// decrease the degree of vertices that links to vertice_i
                    outd[graph[i][j]] --;
                }
                count ++;
            }
            else
            {// no vertice with 0-degree
                return false;
            }
        }
        return true;
    }
};

原文地址:https://www.cnblogs.com/ganganloveu/p/4599465.html