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 @   鸭子船长  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
历史上的今天:
2016-02-17 java String.getBytes()编码问题——String.getBytes(charset)
2016-02-17 设置Eclipse中的tab键为4个空格的完整方法
2016-02-17 linux下的zip命令
2016-02-17 git学习
点击右上角即可分享
微信分享提示