210. 课程表 II(拓扑排序bfs dfs 与207一样)

 

难度中等

现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。

  • 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1] 。

返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组 。

 

示例 1:

输入:numCourses = 2, prerequisites = [[1,0]]
输出:[0,1]
解释:总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。

示例 2:

输入:numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
输出:[0,2,1,3]
解释:总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。
因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3]

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        unordered_map<int,std::vector<int>> map;
        vector<int> ingreed(numCourses,0);
        for(int i = 0; i < prerequisites.size();i++) {
            ingreed[prerequisites[i][0]]++;
            map[prerequisites[i][1]].emplace_back(prerequisites[i][0]);
        }
        queue<int> q;
        for(int i = 0; i < ingreed.size();i++) {
            if (ingreed[i]==0) {
                q.push(i);
            }
        }
        std::vector<int> res;
        while(!q.empty()) {
            int top = q.front();
            q.pop();
            res.emplace_back(top);
            for(auto adj: map[top]) {
                ingreed[adj]--;
                if (ingreed[adj]==0) {
                    q.push(adj);
                }
            }
        }
        //cout << res.size() << endl;
        if (res.size()!=numCourses){
            res.clear();
        }
        return res;
    }
};

 

 

 

class Solution {
public:
    bool has_cycle = false;
    vector<int> post_res;
    void dfs(vector<bool>& visted, vector<bool>& on_path, unordered_map<int,std::vector<int>>& map, int cur_node) {
        if(on_path[cur_node]) {
            has_cycle = true;
        }
        if (visted[cur_node] || has_cycle) {
            return;
        }
        on_path[cur_node] = true;
        visted[cur_node] = true;
        for(auto adj : map[cur_node]) {
            dfs(visted,on_path,map,adj);
        }
        post_res.emplace_back(cur_node);
        on_path[cur_node] = false;
    }
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
    
        unordered_map<int,std::vector<int>> map;
        // 建图
        for(int i = 0; i < prerequisites.size();i++) {
            map[prerequisites[i][1]].emplace_back(prerequisites[i][0]);
        }

        vector<bool> visted = vector<bool>(numCourses,false);
        vector<bool> on_path = vector<bool>(numCourses,false);
        for(int i = 0; i < numCourses; i++) {//注意图中并不是所有节点都相连,所以要用一个 for 循环将所有节点都作为起点调用一次 DFS 搜索算法。
            dfs(visted,on_path,map,i);
        }
        if (has_cycle) {
            post_res.clear();
        }
        std::reverse(post_res.begin(),post_res.end());
        return post_res;
    }
};

 

posted @ 2022-05-11 10:26  乐乐章  阅读(36)  评论(0编辑  收藏  举报