210. 课程表 II

题目重现:

方法一:   根据拓扑排序的人工模拟推导的算法

基本思想就是统计每个节点的入度

入度为0进入队列

在循环中每次 从队列中移出一个元素

并把它指向的元素入度减一  同样的入度为0进入队列

当队列为空 或者 次数达到numCourse 退出循环

class Solution {
public:
 
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        queue<int> q;   vector<int> ans;
        vector<int> count(numCourses,0);
        unordered_map<int,vector<int>> mp;
        for(auto it:prerequisites){
            mp[it[1]].push_back(it[0]);
            count[it[0]]++;
        }

        for(int i=0;i<numCourses;i++){
            if(count[i]==0) q.push(i);
        }
        int cnt=0;
        while(cnt<numCourses && !q.empty()){
            cnt++;
            int head=q.front();
            for(auto it:mp[head]){
                count[it]--;
                if(count[it]==0) q.push(it);
            }
            ans.push_back(head);
            q.pop();
        }
        if(cnt==numCourses) return ans;
        else return vector<int>();
    }
};

方法二:   dfs深度优先搜索

首先对于一个有向无环图 是一定存在拓扑排序的

但是对于一个有环图   是不可能存在拓扑排序的

对于每一个节点 都有三种状态 0未搜索 1搜索中 2搜索完成

每次我们选一个 未搜索0 的节点 ,把它改成搜索中1 然后访问它的相邻节点

如果它的相邻节点都访问完了, 再次回到该节点的时候 ,那么这个节点其实也访问完成了 标记为2 入栈

但是如果在访问过程中出现了 某个节点是 搜索中1 说明出现了环 不存在拓扑排序

假设我们当前访问到了节点u, 发现它的全部相邻节点都已经搜索完成

那么这些相邻节点其实都已经在栈中了 这个时候我们把u入栈

最后的节点访问顺序其实是从栈底部到栈顶的

class Solution {
public: 

    bool valid=true;
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        vector<int> visited(numCourses,0);
        vector<int> result;
        vector<vector<int>> edges(numCourses,vector<int>());
        for(auto it:prerequisites){
            edges[it[1]].push_back(it[0]);
        }
        for(int i=0;i<numCourses;i++){
            if(!visited[i]) 
                dfs(i,visited,edges,result);
        }
        reverse(result.begin(),result.end());
        return valid ? result:vector<int>();
    }

    void dfs(int u,vector<int>& visited,vector<vector<int>>& edges,vector<int>& result){
        visited[u]=1;
        for(auto v:edges[u]){
            if(!visited[v]){
                dfs(v,visited,edges,result);
            }else if(visited[v]==1){
                valid=false;
                return;
            }
        }
        visited[u]=2;
        result.push_back(u);
    }
};

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值