zoukankan      html  css  js  c++  java
  • 课程表

    你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-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。这是不可能的。
     

    提示:

    输入的先决条件是由 边缘列表 表示的图形,而不是 邻接矩阵 。详情请参见图的表示法。
    你可以假定输入的先决条件中没有重复的边。
    1 <= numCourses <= 10^5

    code1:邻接表+bfs;

      从给定的二维数组构造形如a->b邻接表,并计算以b为后继的结点的入度,遍历所有课程,找出入度为0的课程,加入队列

    1. 遍历队列找出入度为0的点,
    2. 把邻接表中以此点为前驱的所有结点的入度都减一,如果发现入度为0的点,加入队列
    3. 直到队列为空,否则重复1-2
    class Solution {
    public:
        bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
            map<int,set<int>> adjcent;//邻接表
            vector<int> indegree(numCourses);//以i为顶点的入度
            for(const auto& edg:prerequisites)
            {
                adjcent[edg[1]].insert(edg[0]);
                ++indegree[edg[0]];
            }
    
            //入度为0的顶点入队列
            queue<int> indegreeZero;
            for(int i=0;i<numCourses;++i)
            {
                if(!indegree[i])
                    indegreeZero.push(i);
            }
    
            int count=0;
            while(!indegreeZero.empty())
            {
                int v=indegreeZero.front();
                indegreeZero.pop();
                ++count;
                auto adj=adjcent[v];
                for(auto i:adj)
                {
                    --indegree[i];//以i为前驱的结点的入度减一
                    if(!indegree[i])
                        indegreeZero.push(i);
                }
            }
            return count==numCourses;
        }
    };

     code:dfs,每个结点有个访问标记flag;

    1. 如果该结点没有被访问过,flag==0
    2. 如果结点点被其他结点启动的dfs访问过,flag==-1
    3. 如果该结点被当前节点启动的dfs访问过,flag==1

    以每个课程为起点,dfs邻接表,判断每个结点起步的dfs是否存在环,若存在返回false,对该结点的邻接点进行dfs

    1. 如果flag==-1,说明被其他结点访问过无需再次遍历,返回true,如果flag==1,说明在此次dfs中2次来到该结点,则存在环,返回false
    2. 将当前访问结点的flag置为1
    3. 对以该结点起步的所有邻接点进行dfs,如果发现换返回false
    4. 把该节点的flag置为-1
    5. 若整个图遍历结束未存在环,返回true
    class Solution {
    private:
        bool dfs(const vector<list<int>>& adjcent,int i,vector<int>& flag)
        {
            if(flag[i]==1)
                return false;
            if(flag[i]==-1)
                return true;
            
            flag[i]=1;
            for(const auto& item:adjcent[i])
            {
                if(dfs(adjcent,item,flag)==false)
                    return false;
            }
            flag[i]=-1;
            return true;
        }
    public:
        bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
            vector<list<int>> adjcent(numCourses,list<int>());
            vector<int> flag(numCourses,0);
            for(const auto& edg:prerequisites)
                adjcent[edg[1]].push_back(edg[0]);
            for(int i=0;i<numCourses;++i)
            {
                if(dfs(adjcent,i,flag)==false)
                    return false;
            }
            return true;
        }
    };
  • 相关阅读:
    扫面线模板
    (动态规划、栈)leetcode 84. Largest Rectangle in Histogram, 85. Maximal Rectangle
    tmux 常见命令汇总
    leetcode 221
    leetcode 319 29
    (贪心)leetcode 392. Is Subsequence, 771. Jewels and Stones, 463. Island Perimeter
    leetcode 982 668
    Python import 同文件夹下的py文件的函数,pycharm报错
    Windows里Anaconda-Navigator无法打开的解决方案
    Windows下 gpu版 Tensorflow 安装
  • 原文地址:https://www.cnblogs.com/tianzeng/p/12486756.html
Copyright © 2011-2022 走看看