zoukankan      html  css  js  c++  java
  • 力扣 第210题

    原题地址:

    https://leetcode-cn.com/problems/course-schedule-ii/

    分析:

    本题是一道经典的「拓扑排序」问题。

    给定一个包含n个节点的有向图G,我们给出它的节点编号的一种排列,如果满足:对于图G中的任意一条有向边(u,v),u在排列中都出现在v的前面。

    那么称该排列是图G的 拓扑排序。可以得到两个结论:

    1、如果图G中存在环,那么图G不存在拓扑排序。

    2、如果图G是有向无环图,那么它的拓扑排序可能不止一种。极端的例子就是:如果图G值包含n个节点没有边,则任意编号排列都可以作为拓扑排序。

    广度优先搜索排列:

    思路:最先被放在拓扑排序中节点一定是 这个节点 没有任何入边。然后当一个节点被放在拓扑排序中后,这个节点指向的所有的入边个数都会减少一。直到所有的节点中没有入边的节点(此时可能会存在环)。

    算法:使用一个队列来进行广度优先搜索。开始时,所有入度为0的节点都被放入队列中,它们就是可以作为拓扑排序最前面的节点,并且他们之间的相对顺序是无关紧要的。

    在广度优先搜索的每一步中,我们取出队首的节点u:

    (1)将u放在拓扑排序中;

    (2)移除u的所有出边,也就是将u的所有相邻节点的入度减少1。如果相邻节点v的入度变为0,那么我们将v放入队列中。

    最后如果拓扑排序中包含这n个节点,则这个就是我们要找的拓扑排序。否则说明存在环。

    class Solution {
    private:
        vector<vector<int>> edges;
        vector<int> indeg;
        vector<int> result;
    public:
        vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
            edges.resize(numCourses);
            indeg.resize(numCourses);
            for(const auto& info : prerequisites) {
                ++indeg[info[0]];
                edges[info[1]].push_back(info[0]);
            }
            
            queue<int> q;
            for (int i = 0; i < numCourses; ++i) {
                if (indeg[i] == 0) {
                    q.push(i);
                }
            }
    
            while(!q.empty()) {
                int u = q.front();
                q.pop();
                result.push_back(u);
                for (int v : edges[u]) {
                    --indeg[v];
                    if (indeg[v] == 0) {
                        q.push(v);
                    }
                }
            }
    
            if (result.size() != numCourses) {
                return {};
            }
    
            return result;
        }
    };
  • 相关阅读:
    C#操作REDIS例子
    A C# Framework for Interprocess Synchronization and Communication
    UTF8 GBK UTF8 GB2312 之间的区别和关系
    开源项目选型问题
    Mysql命令大全——入门经典
    RAM, SDRAM ,ROM, NAND FLASH, NOR FLASH 详解(引用)
    zabbix邮件报警通过脚本来发送邮件
    centos启动提示unexpected inconsistency RUN fsck MANUALLY
    rm 或者ls 报Argument list too long
    初遇Citymaker (六)
  • 原文地址:https://www.cnblogs.com/xiaohaigegede/p/14233109.html
Copyright © 2011-2022 走看看