当前位置: 首页 > article >正文

【LeetCode】【算法】209. 课程表

LeetCode 209. 课程表

题目描述

你这个学期必须选修numCourses门课程,记为0到numCourses- 1 。
在选修某些课程之前需要一些先修课程。先修课程按数组prerequisites给出,其中 prerequisites[i] = [a_i,b_i] ,表示如果要学习课程a_i则必须先学习课程b_i。
例如,先修课程对[0, 1]表示:想要学习课程0,你需要先完成课程1。
请你判断是否可能完成所有课程的学习?如果可以,返回true;否则,返回false。

思路

这是一个经典的拓扑排序问题,什么是拓扑排序问题?我理解就是需要判断先完成什么事儿再完成什么事儿的那种问题
可以考虑通过建立一个图,对于入度为0的图先开始做搜索,看最后能不能把所有的图节点遍历掉。
第一步:根据给定的prerequisites建立一个类型为List<List<Integer>>edges的列表,其中下标i表示第i门课程,List<Integer>则表示第i门课程的后置课程;同时还有一个indeg=new int[numCourses]数组,该数组中记录每门课程有多少门前置课程
第二步:建立队列,遍历indeg数组,寻找那些前置课程门数为0的课程,并入队到队列尾
第三步:建立一个visited变量存储学习的课程数量,while(队列不为空时)

  • ①出队首元素;
  • ②学习课程数+1;
  • ③通过上面的第一步的List<List<Integer>> edges获得该门课程的所有后置课程,遍历里边的元素for (int v:edges.get(u))对于里面的元素执行:
    --indeg[v];因为该门课程的前置课程数量-1
    if (indeg[v]==0)说明该元素此时入度为0(没有前置课程了),入队到队列尾

第四步:返回visited == numCourses,就知道能否学完所有课程了

代码

class Solution {
    List<List<Integer>> edges;
    int[] indeg;

    public boolean canFinish(int numCourses, int[][] prerequisites) {
        // 建立图以后做搜索
        edges = new ArrayList<>();
        for (int i = 0; i < numCourses; i++){
            edges.add(new ArrayList<>());
        }
        indeg = new int[numCourses];
        for (int[] prerequisite : prerequisites) {
            edges.get(prerequisite[1]).add(prerequisite[0]);
            ++indeg[prerequisite[0]]; // 记录这个位置有几个子节点,便于后续做广度优先搜索 -> 但是真的有必要吗?edges[prerequisite[0]]的长度不行吗
        }

        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < numCourses; i++) {
            if (indeg[i] == 0){ // 找到入度为0的节点开始广度优先搜索
                queue.offer(i);
            }
        }

        int visited = 0;
        while (!queue.isEmpty()){
            ++visited;
            int u = queue.poll(); // 出队
            for (int v: edges.get(u)){ // 广度优先搜索,里面的内容入队
                --indeg[v];
                if (indeg[v] == 0){ // 直到这个节点不再被其他节点所指,才能入队继续遍历它下面的节点
                    queue.offer(v);
                }
            }
        }

        return visited == numCourses;
    }
}

http://www.kler.cn/a/389289.html

相关文章:

  • 以往运维岗本人面试真题分享
  • 服务号消息折叠折射出的腾讯傲慢:上云会不会也一样?
  • aws(学习笔记第十二课) 使用AWS的RDS-MySQL
  • AcWing 300 任务安排1
  • uniapp打包华为,提示请提供64位版本软件包后再提交审核
  • 卸载一直显示在运行的应用
  • 蓝桥杯备赛(持续更新)
  • 【C语言刷力扣】66.加一
  • 京东商品SKU信息的“窃听风云”:Python爬虫的幽默之旅
  • 搜维尔科技:【应用】Xsens在荷兰车辆管理局人体工程学评估中的应用
  • 『 Linux 』网络传输层 - TCP(三)
  • 基于百度飞桨paddle的paddlepaddle2.4.2等系列项目的运行
  • Tidb数据恢复
  • [CKS] Create/Read/Mount a Secret in K8S
  • 软考中级 软件设计师 上午考试内容笔记(个人向)Part.3
  • Linux 消息队列
  • go template 模板字符串
  • std::thread线程通知、等待、让渡
  • 绿色能源发展关键:优化风电运维体系
  • 初学Java基础---Day21---正则表达式,日期类,Math类,Random类,System类,Runtime类,大数值运算类,
  • 【cursor添加azure】在cursor中添加azure的openai api
  • 面向对象试题带答案
  • Linux网络管理和修改配置文件
  • HBase 安装与基本操作指南
  • 机器学习与深度学习-1-线性回归从零开始实现
  • MyBatis xml 文件中 SQL 语句的小于号未转义导致报错