• 210. 课程表 II


    题目描述

    现在你总共有 numCourses 门课需要选,记为 0 到 numCourses - 1。给你一个数组 prerequisites ,其中 prerequisites[i] = [ai, bi] ,表示在选修课程 ai 前 必须 先选修 bi 。

    例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示:[0,1] 。
    返回你为了学完所有课程所安排的学习顺序。可能会有多个正确的顺序,你只要返回 任意一种 就可以了。如果不可能完成所有课程,返回 一个空数组 。

    示例 1:

    输入:numCourses = 2, prerequisites = [[1,0]]
    输出:[0,1]
    解释:总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。
    示例 2:

    输入:numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
    输出:[0,2,1,3]
    解释:总共有 4 门课程。要学习课程 3,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 0 之后。
    因此,一个正确的课程顺序是 [0,1,2,3] 。另一个正确的排序是 [0,2,1,3] 。
    示例 3:

    输入:numCourses = 1, prerequisites = []
    输出:[0]

    提示:
    1 <= numCourses <= 2000
    0 <= prerequisites.length <= numCourses * (numCourses - 1)
    prerequisites[i].length == 2
    0 <= ai, bi < numCourses
    ai != bi
    所有[ai, bi] 互不相同


    做题思路

    • 求我们需要学习课表的顺序,不存在返回空数组

    • 这个题目考察 BFS

    • 需要我们对图的概念有一定的了解

    • 入度 出度 需要直到

    • [a,b] 学习a必须要学习b a —> b

    • 此时我们就说 a的入度为0 b的入度为1

    • 知道了上面这个概念之后,继续分析

    • 我们可以创建一个数字,一个集合

    • 数组保存从课程 0-numCourse 所有入度的课程

      (通俗来说就是 我需要依赖几个课程 )

    • 集合保存 都谁依赖我

    • 注意这两个数据结构的含义,在本题所代表的意义

    • 初始化之后我们就用一个队列记录入度为0的课程

    • 每次从队列取出一个元素,然后开始消消乐

    • 拿去出来的元素,结合 我们定义的集合/数组

      遍历集合(也就是说 “被依赖的课程已经学习过了” “接下来看看谁需要我?就可以将需要我对应数组的值减去一个了”),如果减完之后发现数组对应的值也为0 (入度为0)就也加入到数组中去,接着遍历,知道队列为空

    • 在这之间我们还需要一个集合记录 已经学习过的课程

      最后拿这个集合的个数和我们需要学习的课程个数比较是否相等

    代码实现

    class Solution {
        public int[] findOrder(int numCourses, int[][] prerequisites) {
            List<Integer>[] dependicy=new ArrayList[numCourses];
            int[] index=new int[numCourses];
            List<Integer> res=new ArrayList<>();
            for(int i=0;i<prerequisites.length;i++){
                int a=prerequisites[i][0];
                int b=prerequisites[i][1];
                index[a]++;
                if(dependicy[b]==null){
                    dependicy[b]=new ArrayList<Integer>();
                }
                dependicy[b].add(a);
            }
            Deque<Integer> queue=new ArrayDeque<>();
            for(int i=0;i<index.length;i++){
                if(index[i]==0){
                    queue.offer(i);
                }
            }
            while(!queue.isEmpty()){
                int relied=queue.poll();
                if(dependicy[relied]!=null){
                    for(int i=0;i<dependicy[relied].size();i++){
                        int rely=dependicy[relied].get(i);
                        index[rely]--;
                        if(index[rely]==0){
                            queue.offer(rely);
                        }
                    }
                }
    
                res.add(relied);
            }
            if(res.size()!=numCourses)return new int[0];
            int[] result=new int[numCourses];
            for(int i=0;i<numCourses;i++){
                result[i]=res.get(i);
            }
            return result;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    题目链接

    210. 课程表 II

  • 相关阅读:
    grpc c++部署
    node的api使用——URL——get方法——网页爬虫——node事件——path路径——判断文件类型——fs四种异步封装——客户端文件验证发送
    Java Web之Servlet技术
    记录 android studio 通过安装NDK 编译C文件,得到需要的so文件
    RabbitMQ和Minio实现头像存储
    理解ASP.NET Core - 授权(Authorization)
    父子进程、僵尸进程和孤儿进程
    Android打造专有Hook第四篇,实战增量代码规范检查
    软工UML画图
    [开源]MIT协议,开源论坛程序,拥有友好的用户界面和操作体验
  • 原文地址:https://blog.csdn.net/C_x_330/article/details/127700769