Leetcode 207. 课程表 && 210. 课程表 II

题解:labuladong

题目:

207. 课程表

 

注意,[1,0]代表前置课程0,才能学课程1

 

思路:

可以将其转换为有向图是否有环的问题。方向是由前置课程指向后置课程,以此来构建有向图。在递归遍历有向图的过程中,通过visited来进行剪枝,即访问过的结点不再访问。通过onPath来记录走过的路径,进入结点设true,退出结点设false。当遍历的节点onPath=true时,说明路径有环。

class Solution {
public:
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        onPath.resize(numCourses);
        visited.resize(numCourses);
        hascycle=false;
        vector<vector<int>> graph = buildGraph(numCourses,prerequisites);
        for(int i=0;i<numCourses;++i){
            traverse(graph, i);
        }
        return !hascycle;
    }
    vector<vector<int>> buildGraph(int numCourses, vector<vector<int>>& prerequisites){
        vector<vector<int>> graph;
        graph.resize(numCourses);
        for(int i=0;i<prerequisites.size();++i){
            int from=prerequisites[i][1];
            int to=prerequisites[i][0];
            graph[from].push_back(to);
        }
        return graph;
    }
    void traverse(vector<vector<int>>& graph, int s){
        if(onPath[s]){
            hascycle=true;
            return;
        }
        if(visited[s]){
            return;
        }
        visited[s]=true;
        onPath[s]=true;
        for(int i=0;i<graph[s].size();++i){
            traverse(graph,graph[s][i]);
        }
        onPath[s]=false;
    }
    vector<bool> onPath;
    vector<bool> visited;
    bool hascycle;
};

 

210. 课程表 II

题目:

 

 

思路:

在判断是否有环的基础上,给出一个遍历的排序,要求前置在前。

这里判断有环与之前一样。

排序:先进行后序遍历,这样参照二叉树的图来看,根节点在最后,根节点也就是所有节点的前置结点。然后将遍历得到的序列进行反转,就将所有前置结点置前,实现了对应排序。

 

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        hasCycle=false;
        visited.resize(numCourses);
        onPath.resize(numCourses);
        graph = buildGraph(numCourses,prerequisites);
        for(int i=0;i<numCourses;++i){
            traverse(graph,i);
        }
        if(hasCycle){
            return vector<int>();
        }
        std::reverse(postorder.begin(), postorder.end());
        return postorder;
    }
    vector<vector<int>> buildGraph(int numCourses, vector<vector<int>>& prerequisites){
        vector<vector<int>> graph(numCourses);
        for(int i=0;i<prerequisites.size();++i){
            int from=prerequisites[i][1];
            int to=prerequisites[i][0];
            graph[from].push_back(to);
        }
        return graph;
    }
    void traverse(vector<vector<int>>& graph, int s){
        if(onPath[s]){
            hasCycle=true;
        }
        if(visited[s]){
            return;
        }
        onPath[s]=true;
        visited[s]=true;
        for(int i=0;i<graph[s].size();++i){
            traverse(graph,graph[s][i]);
        }
        onPath[s]=false;
        postorder.push_back(s);
    }
    vector<vector<int>> graph;
    vector<bool> visited;
    vector<bool> onPath;
    vector<int> postorder;
    bool hasCycle;
};

 

posted @ 2022-02-17 16:01  鸭子船长  阅读(41)  评论(0编辑  收藏  举报