zoukankan      html  css  js  c++  java
  • 207. 课程表(拓扑排序)

    207. 课程表

    难度⭐⭐

    你这个学期必须选修 numCourse 门课程,记为 0numCourse-1

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

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

    示例 1:

    输入: 2, [[1,0]] 
    输出: true
    解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。
    

    分析

    根据题意可以将课程之间的关系以有向图的方式存储,节点之间的连接表示关系,边的权重可以用先修课程数表示(记为节点的入度)

    1. 遍历求出每个节点的入度(先修数),并存储图
    2. 由于入度数表示先修数,入度为0的课程可以修
    3. 将入度为0节点入队列(BFS),每有一个邻接节点就将入度减一
    4. 判断可修课程数是否等于总课数
    class Solution:
        def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
            from collections import defaultdict
            graph = defaultdict(list)
            indeg = [0]*numCourses
            #存储图以及入度
            for rel in prerequisites:
                indeg[rel[0]] += 1
                graph[rel[1]].append(rel[0])
    
            #BFS 入度0节点入队列 
            res = []
            q = [cou for cou,deg in enumerate(indeg) if deg == 0]
            while q:
                node = q.pop(0)
                res.append(node)
                for i in graph[node]:#判断邻接节点入度是否为0(可以入队列)
                    indeg[i] -= 1
                    if indeg[i] == 0:
                        q.append(i)
            return True if len(res) == numCourses else False
    
    class Solution {
        public boolean canFinish(int numCourses, int[][] prerequisites) {
            //定义邻接矩阵和存储入度的数组
            List<List<Integer>> graph = new ArrayList<List<Integer>>();
             for (int i = 0; i < numCourses; ++i) {
                graph.add(new ArrayList<Integer>());
            }
            int[] indeg = new int[numCourses];
    
            for(int[] info : prerequisites){
                indeg[info[0]] += 1;
                graph.get(info[1]).add(info[0]);
            }
    
            //BFS 创建队列 入度为0入队
            Queue<Integer> q = new LinkedList<Integer>();
            for(int i=0; i<numCourses; i++){
                if(indeg[i] == 0) q.offer(i);
            }
    
            while(!q.isEmpty()){
                int node = q.poll();
                numCourses--;
                for (int v: graph.get(node)) {
                    --indeg[v];
                    if (indeg[v] == 0) {
                        q.offer(v);
                    }
                }
            }
            return numCourses == 0;
        }
    }
    
  • 相关阅读:
    linux分析工具之vmstat详解
    linux分析工具之top命令详解
    hadoop之yarn详解(命令篇)
    hadoop之yarn详解(基础架构篇)
    linux分析利刃之sar命令详解
    hadoop之mapreduce详解(优化篇)
    linux之find命令详解
    一个毫无用处的公众号封面生成器
    一个简单的计时器对比各种可迭代对象定义方式的速度区别
    python中的迭代器和生成器
  • 原文地址:https://www.cnblogs.com/gongyanzh/p/13431714.html
Copyright © 2011-2022 走看看