一、题目
二、思路
- 题目:每个课程看作一个节点,先修关系为节点的有向边,目标是判断能否根据课程安排关系,成功学完所有课程。
- 拓扑排序算法:
- 统计每个节点入度
- 将所有入度为0的节点(注意是可以有多个入度节点,如下图)加入队列
que
- 对第二点中的队列
que
,遍历每个入度为0的节点,将其相邻节点的入度减1,如果相邻节点相邻节点
- 重复第三点直到最后
que
队列为空:如果所有节点此时入度为0,则说明课程的学习顺序合理,能够完整学完课程;如果还有节点入度不为0,则说明图存在环,课程无法完成。
defaultdict(list)
表示字典里的value
为list列表,我们用来作为邻接列表,和其他dict的区别是,若key为空,defaultdict
字典会返回一个空列表,而不是直接返回异常。
三、Python代码
from collections import defaultdict, deque
class Solution:
def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
in_degree = [0] * numCourses
adj = defaultdict(list)
for out, pre in prerequisites:
in_degree[out] += 1
adj[pre].append(out)
que = deque([i for i in range(numCourses) if in_degree[i] == 0])
while que:
node = que.popleft()
for neighbor in adj[node]:
in_degree[neighbor] -= 1
if in_degree[neighbor] == 0:
que.append(neighbor)
return sum(in_degree) == 0