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;
  • 相关阅读:
    OC中的block
    tips: NSCopying和NSMutableCopying
    tips: @property 、@synthesize和@dynamic
    静态库SDK引发的符号冲突
    复杂业务app中跨业务页面调用方案
    AOP
    【HTML 初学】3、HTML标题
    【HTML 初学】2、HTML属性
    【HTML 初学】1、HTML元素
    【Java编程思想】二、一切都是对象
  • 原文地址:https://www.cnblogs.com/zhudingtop/p/11596387.html
Copyright © 2011-2022 走看看