【图论】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
,即需求列表prerequisites
中ai
为C
的需求个数- 出度
n[1] 列表
:有多少先修课程C→
,即需求列表prerequisites
中bi
为C
的所有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 1for [ai, bi] in prerequisites:graph[ai][0] += 1graph[bi][1].append(ai)to_learn = [_ for _ in range(numCourses)] # ---------------- step 2def find_Course():for C in to_learn: # 从 to_learn 中找寻if graph[C][0] == 0: ## 找到啦,开始进行学习to_learn.remove(C) ## 移除 Cfor _ in graph[C][1]: ## 处理所有 C→graph[_][0] -= 1return C ## 返回符合要求的课程 Creturn None ## 均不符合要求:不可能学完所有课程 (存在环路)while True: # --------------------------------------------- step 3if not to_learn: return True # ---------------------- step 3.1C = find_Course() # --------------------------------- step 3.2if C==None : return False # ------------------------- step 3.3
希望对你有帮助呀!!💜💜 如有更好理解的思路,欢迎大家留言补充 ~ 一起加油叭 💦
欢迎关注、订阅专栏 【力扣详解】谢谢你的支持!
🔥 LeetCode 热题 HOT 100