leetcode(力扣) 207. 课程表1+2(图的构造与遍历,清晰思路,完整模拟)

文章目录

  • 题目描述
  • 思路分析
  • 完整代码

题目描述

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

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

示例 2:
输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
输出:false
解释:总共有 2 门课程。学习课程 1 之前,你需要先完成​课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。

思路分析

先构造图思路。
假设有:[[3, 0], [3, 1], [4, 1], [4, 2], [5, 3], [5, 4]]

则构造图:
在这里插入图片描述
也就是说:

  • 每次只能选入度为 0 的课,因为它不依赖别的课,是当下你能上的课。
  • 假设选了 0,课 3 的先修课少了一门,入度由 2 变 1。
  • 接着选 1,导致课 3 的入度变 0,课 4 的入度由 2 变 1。
  • 接着选 2,导致课 4 的入度变 0。
  • 现在,课 3 和课 4 的入度为 0。继续选入度为 0 的课……直到选不到入度为 0 的课。

所以现在的思路就很简单了,所有入度为0的节点都是可以直接学习的课。

我们只需要先设置两个数组chudu和rudu,记录入度和出度情况。

比如对于:[[1,0],[2,0],[3,1],[3,2]]
则:
chudu = [[1, 2], [3], [3], []] 即 i号课的出度指向 chudu[i]
rudu = [0, 1, 1, 2] 即 i号课的入度有rudu[i]个课。

直接代码构造这俩数组:

        for i in prerequisites:
            chudu[i[1]].append(i[0])
            rudu[i[0]]+=1

然后构造一个队列,将所有入度为0的课加入。

for i in range(len(rudu)):
   if rudu[i] == 0:
       queue.append(i)

后面就简单了,比如有[1,2] ,图表示就是2->1。

  • 此时2的入度为0,则2被加入队列中,拿出队列中的2,看看2是谁的入度
  • 显然2是1的入度,所以要将1的入度数减去1
  • -当1的入度数为0的时候,表示1也是可以学习的课了,将1也加入到队列中。

第二道题 就是课程表2,实际上和课程表1 基本一样。课程表1是计数,然后和题目所给的numCourses 做比较,在课程表2中更改一下,设置一个res答案数组,直接在count计数的位置变成记录答案数组就行了。

完整代码

### 课程表1
class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:

       # 构造出入度列表
        chudu = [[] for x in range(numCourses)]
        rudu = [0]*numCourses
        queue = []
        count = 0

        for i in prerequisites:
            # 添加依赖它的后续课
            chudu[i[1]].append(i[0])
            rudu[i[0]] += 1

        for i in range(numCourses):
            if rudu[i] == 0:
                queue.append(i)

        while queue != []:  
            for i in range(len(queue)):
                temp = queue.pop(0)
                count += 1
                for x in chudu[temp]:
                    rudu[x] -= 1
                    if rudu[x] == 0:
                        queue.append(x)

        return count==numCourses

### 课程表2
class Solution:
    def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:


        rudu = [0] * numCourses
        chudu = [[] for _ in range(numCourses)]

        queue = []
        res = []
        
        for i in prerequisites:
            chudu[i[1]].append(i[0])
            rudu[i[0]]+=1
        print(chudu,rudu)
        for i in range(len(rudu)):
            if rudu[i] == 0:
                queue.append(i)
        while queue!=[]:
            for i in range(len(queue)):
                temp = queue.pop()    # temp号课已经学习了
                res.append(temp)
                for j in chudu[temp]: # 遍历所有以temp为前置的课
                    rudu[j]-=1
                    if rudu[j] == 0:
                        queue.append(j)
        return res if len(res) == numCourses else []


        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/131338.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网易云音乐未登录接口返回301

网易云音乐 NodeJS 版 API (neteasecloudmusicapi.js.org) 上面是网易云音乐的官方API接口文档 当我调用接口发送请求的时候部分接口数据是需要登录之后进行获取的,但是当我发送请求的时候原生js项目中的跨端问题是比较难解决的。 遇到的问题:跨端请求…

超详细!Linux内核内存规整详解

1.前言 伙伴系统作为内核最基础的物理页内存分配器,具有高效、实现逻辑简介等优点,其原理页也尽可能降低内存外部碎片产生,但依然无法杜绝碎片问题。外部碎片带来的最大影响就是内存足够,但是却无法满足内存分配需求,如…

35 字段类型不匹配 影响 使用索引?

前言 这是一个经常能够看到的问题, 又或者 经常在面试中碰到 如果 索引字段类型 不匹配, 然后 不会使用索引 这里 我们来看一下 具体的情况 测试表结构如下 CREATE TABLE tz_test (id int(11) unsigned NOT NULL AUTO_INCREMENT,field1 varchar(128) DEFAULT NULL,PRIMA…

开放领域问答机器人1

开放领域问答机器人是一种智能机器人,它不受限制,可以回答任何问题。这种机器人主要通过自然语言处理技术来理解用户的问题,并从大量的数据中获取相关信息,以提供准确的答案。它的应用领域广泛,包括客户服务、教育、医…

GS3661V1 3.7升压5V 3A SOT23-5封装 外置MOS 升压芯片 单节锂电升压5V 2.5-3A

GS3661V1 3.7升压5V 3A SOT23-5 外置MOS 升压芯片 单节锂电升压5V 2.5-3A

贝锐向日葵亮相云栖大会,携手无影推出全新“云桌面”功能

2023年10月31日-11月2日,一年一度的云栖大会如期举办,本届云栖大会主题为“计算,为了无法计算的价值”,国民级远程控制品牌“贝锐向日葵”亮相云栖大会,参与了以“云电脑”为主题的聚合话题活动。 活动现场&#xff0c…

Vue3组件

组件(Component)是 Vue.js 最强大的功能之一。 组件可以扩展 HTML 元素,封装可重用的代码。 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树: 每个 Vue 应用…

基于SSM的食用菌菌棒溯源系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…

广告算法资料汇总【建设中】

业内大佬 阿里妈妈技术 张俊林 王喆 萧瑟 朱小强 综合 付海军:基于互联网广告发展演变和思考(附视频讲解PPT) 广告算法工程师入门_广告与算法的博客-CSDN博客 广告算法学习笔记 20万、50万、100万的算法工程师,到底有什么区别…

Linux编辑器---vim的使用

Vim是一个高度可配置的文本编辑器,它是操作Linux的一款利器,旨在高效地创建和更改任何类型的文本。这款编辑器起源于"vi",并在此基础上发展出了众多新的特性。Vim被普遍推崇为类Vi编辑器中最好的一个,事实上真正的劲敌来…

【算法与数据结构】131、LeetCode分割回文串

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:本题仍然使用回溯算法的一般结构。加入了一个判断是否是回文串的函数,利用起始和终止索引进…

程序员的护城河:技术、创新与软实力的完美融合

作为IT行业的从业者,我们深知程序员在保障系统安全、数据防护以及网络稳定方面所起到的重要作用。他们是现代社会的护城河,用代码构筑着我们的未来。那程序员的护城河又是什么呢?是技术能力的深度?是对创新的追求?还是…

【深度】详细解读与评测OpenAI DevDay的最新API更新与应用

原文:https://www.toutiao.com/article/7299498535408665088/?log_fromd9f79b9fe2182_1699572121760 专注LLM深度应用,关注我不迷路 周二凌晨,全球无数AI科技工作者与极客们翘首以盼的首届OpenAI开发者大会上,仅仅四十分钟的主…

win11下安装odoo17(conda python11)

win11下安装odoo17 odoo17发行了,据说,UI做了很大改进,今天有空,体验一下 打开官方仓库: https://github.com/odoo/odoo 默认的版本已经变成17了 打开odoo/odoo/init.py,发现对python版本的要求也提高了…

Vue的vant notify组件报错Notify is not defined

解决方法: 原创作者:吴小糖 创作时间:2023.11.10

sCrypt 现在支持 Ordinals 了

比特币社区对 1Sat Ordinals 的接受度正在迅速增加,已有超过 4800 万个铭文被铸造,这一新创新令人兴奋不已。 尽管令人兴奋,但 Ordinals 铭文的工具仍然不发达,这使得使用 Ordinals 进行构建具有挑战性。 更具体地说,缺…

一文读懂RestCloud AppLink

RestCloud AppLink是什么? RestCloud AppLink 是一种应用程序集成解决方案,它提供了一套工具和技术,用于实现不同应用程序之间的无缝集成和交互。平台旨在解决企业中应用程序之间数据孤岛、信息孤立和业务流程不畅的问题,提高企业…

【数据结构】单链表之--无头单向非循环链表

前言:前面我们学习了动态顺序表并且模拟了它的实现,今天我们来进一步学习,来学习单链表!一起加油各位,后面的路只会越来越难走需要我们一步一个脚印! 💖 博主CSDN主页:卫卫卫的个人主页 &#x…

云计算:未来世界的超级英雄

在这个充满奇妙的时代,云计算被赋予了超级英雄的力量。它以其高效、可靠的数据处理能力,成为了推动智能科技发展的核心引擎。想象一下,你的智能家居设备能够通过云计算与你互动,根据你的需求智能调节温度、照明、音乐,…

数据库安全:MySQL 身份认证漏洞(CVE-2012-2122)

数据库安全:MySQL 身份认证漏洞(CVE-2012-2122) MySQL 身份认证漏洞是一个身份认证绕过漏洞,该漏洞的核心原理涉及到 MySQL 在处理身份认证时的一个安全缺陷,这个漏洞可以使攻击者可以绕过安全身份认证,从…