LeetCode Course Schedule(Topological Sorting)

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.

解法一(BFS):

class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<unordered_set<int>> graph = make_graph(numCourses, prerequisites);
        vector<int> indegree = compute_indegree(graph);
        for(int i = 0; i<numCourses; i++){
            int j = 0;
            for(; j<numCourses; j++)
                if(indegree[j] == 0)
                    break;
            if(j == numCourses) return false;
            indegree[j] = -1;
            for(int neigh: graph[j])
                indegree[neigh]--;
        }
        return true;
    }
private:
    vector<unordered_set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<unordered_set<int>> graph(numCourses);
        for(auto pre: prerequisites)
            graph[pre.first].insert(pre.second);
        return graph;
    }
    vector<int> compute_indegree(vector<unordered_set<int>> graph) {
        vector<int> indegree(graph.size(), 0);
        for(auto neighbors: graph)
            for(int neigh: neighbors)
                indegree[neigh]++;
        return indegree;
    }
};

入度为0的结点也可以用栈或队列维护,用一个计数变量判断到底有多少个结点可以出队。

解法二(DFS):

class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<unordered_set<int>> graph = make_graph(numCourses, prerequisites);
        vector<bool> visited(numCourses, false), onpath(numCourses, false);
        for(int i = 0; i<numCourses; i++)
            if(!visited[i] && dfs_cycle(graph, i, visited, onpath))
                return false;
        return true;
    }
private:
    vector<unordered_set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<unordered_set<int>> graph(numCourses);
        for(auto pre: prerequisites)
            graph[pre.first].insert(pre.second);
        return graph;
    }
    bool dfs_cycle(vector<unordered_set<int>>& graph, int node, vector<bool>& visited, vector<bool>& onpath) {
        if(visited[node]) return false;
        onpath[node] = visited[node] = true;
        for(int neigh: graph[node])
            if(onpath[neigh] || dfs_cycle(graph, neigh, visited, onpath))
                return true;
        onpath[node] = false;
        return false;
    }
};

维护了两个标志数组,一个是全局的,一个是本路径的。

详细解析参考:
https://leetcode.com/problems/course-schedule/discuss/58509/18-22-lines-C++-BFSDFS-Solutions

附:
拓扑排序的算法(DFS):
https://www.geeksforgeeks.org/topological-sorting/

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,438评论 0 10
  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,868评论 0 23
  • 一对一 用户和文章 一对多 文章和评论 多对多 用户和角色一个用户可以拥有多个角色,一个角色下面可以有多个用户us...
    邱杉的博客阅读 514评论 0 50
  • 我想揉碎自己 然后重装 不一样的过去 不一样的现在 只有一样的一个我 还在这里
    田萍阅读 142评论 2 5
  • 人生的路,从蹒跚学步开始。 人生百年,相比之下是短暂的。每一步都会匆匆而过,不管一路的风景如何,是成功是失败,此时...
    陆问心阅读 99评论 0 0