【Leetcode207】课程表(拓扑排序)

一、题目

在这里插入图片描述

二、思路

  • 题目:每个课程看作一个节点,先修关系为节点的有向边,目标是判断能否根据课程安排关系,成功学完所有课程。
  • 拓扑排序算法:
    • 统计每个节点入度
    • 将所有入度为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:
        # 1. 统计每个节点的入度
        in_degree = [0] * numCourses
        adj = defaultdict(list)  # 邻接列表, dict, key: node; value: list
        for out, pre in prerequisites:
            in_degree[out] += 1
            adj[pre].append(out)
        # 2. 将入度为0的节点加入队列que
        que = deque([i for i in range(numCourses) if in_degree[i] == 0])
        # 3. 遍历队列que,对out的入度数减一操作, 拓扑排序
        while que:
            node = que.popleft()   # 队列出元素
            for neighbor in adj[node]:
                in_degree[neighbor] -= 1
                if in_degree[neighbor] == 0:
                    que.append(neighbor)
        # 4. 判断是否还有节点的入度不为0, 若为0则成功
        return sum(in_degree) == 0

猜你喜欢

转载自blog.csdn.net/qq_35812205/article/details/128502418