zoukankan      html  css  js  c++  java
  • 【LeetCode】课程表

    【问题】现在你总共有 n 门课需要选,记为 0 到 n-1。

    在选修某些课程之前需要一些先修课程。例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]

    给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?

    示例 1:
    输入: 2, [[1,0]] 
    输出: true
    解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。
    示例 2:
    输入: 2, [[1,0],[0,1]]
    输出: false
    解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0;并且学习课程 0 之前,你还> 应先完成课程 1。这是不可能的。
    说明:
    
    输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。
    你可以假定输入的先决条件中没有重复的边。

    【思路】由于本题目中的每个课程之间都有相应的联系,因此我们可以根据课程关系来构建一个有向图,如果在这个有向图中存在一个循环,那么则不能学完所有的课程,因为每个课程都需要每个先决条件的课程。一个很简单的思路是使用拓扑排序算法,可以判断一个循环是否存在于一个有向图中。

    拓扑排序算法:计算图中所有节点的入度,如果某些节点的入度为零,则压入到队列todo中,接着循环弹出队列中的节点(即入读为零的节点),同时将下一个节点中入度为零的节点压入队列中,如果最后图都可以分离开,也就在此过程中,每个节点在分离时都可能入度为零。说明这个有向图中没有循环,否则则有循环。

    拓扑排序
    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
            std::unordered_map<int, int> indegree;
            for(auto& v : prerequisites) {
                indegree[v[0]]++;
            }
            queue<int> que;
            for(int i=0; i<numCourses; ++i) {
               if(indegree[i] == 0) {
                   que.push(i);
               }
            }
            int cnt = 0;
            while(!que.empty()) {
                int k = que.front();
                que.pop();
                cnt++;
                for(auto& v : prerequisites) {
                    if(k == v[1]) {
                        if(--indegree[v[0]] == 0) {
                            que.push(v[0]);
                        }
                    }
                }
            }
            if(cnt != numCourses)
                return false;
            return true;
  • 相关阅读:
    人月神话 画蛇添足
    人月神话 贵族专制和民主政治
    人月神话 外科手术队伍
    人月神话 焦油坑
    体温填报(五)
    体温填报(四)
    qwb与学姐
    qwb VS 去污棒
    1045 快速排序(25 分)
    LibreOJ #107. 维护全序集
  • 原文地址:https://www.cnblogs.com/zhudingtop/p/11596387.html
Copyright © 2011-2022 走看看