LeetCode 热题 HOT 100 (009/100)【宇宙最简单版】

【图论】No. 0207 课程表【中等】👉力扣对应题目指路

希望对你有帮助呀!!💜💜 如有更好理解的思路,欢迎大家留言补充 ~ 一起加油叭 💦
欢迎关注、订阅专栏 【力扣详解】谢谢你的支持!

题目描述:你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi

  • 请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false

  • 示例 :

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

  • 课程拓扑图示例:

🔥 思路:从不需要先修课程的课程 C 进行学习,逐步迭代拓扑图,直至所有课程都被进行学习

  • 进行学习:从拓扑图中移除课程 C,且去掉 C 为先修课程的要求
    • 以 C=C1为例:移除 C1,且去掉 C1 指向其他的有向边 C1 →C3, C1 →C8
  • 逐步迭代-每步选择一个不需要先修课程 (即没有指向 →C 的有向边) 的课程 C
    • 如果图中课程节点均不符合要求,说明不可能学完所有课程 (存在环路)
  • 如果所有课程都被进行学习(图中节点均被移除)了,说明可以学完所有课程

参考如上思路,给出详细步骤如下:

  • 步骤一⭐创建 graph = [n1, n2, …]: 列表,包含 numCourses 个课程节点,每个课程C对应的节点 n 包含
    • 入度n[0]:有多少先修课程 →C,即需求列表prerequisitesaiC 的需求个数
    • 出度n[1] 列表:有多少先修课程 C→,即需求列表prerequisitesbiC 的所有 ai
      • 记录 C→ 的后续课程 ,方便去掉 C 为先修课程的要求: 所以记录所有 ai 而非仅个数
  • 步骤二⭐创建初始 to_learn 列表:保存目前拓扑图中剩余的课程
    • 逐步迭代时从 to_learn 中找寻下一个符合要求的课程 C
  • 步骤三⭐开始逐步迭代拓扑图 graph
    • 如果所有课程都被进行学习(to_learn 为空)了,返回 True
    • 找到下一个满足条件的课程 C进行学习
    • 如果上步找不到 C,说明不可能学完所有课程 (存在环路),返回 False
 class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        graph = [[0, []] for _ in range(numCourses)]  # ------------- step 1
        for [ai, bi] in prerequisites:
            graph[ai][0] += 1
            graph[bi][1].append(ai)
        
        to_learn = [_ for _ in range(numCourses)]  # ---------------- step 2

        def find_Course():
            for C in to_learn:  # 从 to_learn 中找寻
                if graph[C][0] == 0:  		## 找到啦,开始进行学习
                    to_learn.remove(C)  	## 移除 C
                    for _ in graph[C][1]:  	## 处理所有 C→
                        graph[_][0] -= 1
                    return C  				## 返回符合要求的课程 C
            return None  					## 均不符合要求:不可能学完所有课程 (存在环路)

        while True:  # --------------------------------------------- step 3
            if not to_learn: return True  # ---------------------- step 3.1
            C = find_Course()  # --------------------------------- step 3.2
            if C==None : return False  # ------------------------- step 3.3

希望对你有帮助呀!!💜💜 如有更好理解的思路,欢迎大家留言补充 ~ 一起加油叭 💦
欢迎关注、订阅专栏 【力扣详解】谢谢你的支持!
🔥 LeetCode 热题 HOT 100

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值