【图解】拓扑排序(210. 课程表 II)


思路

这是一个典型的拓扑排序题目, 对拓扑排序不熟悉的,可以看下这个文章 - 揭开「拓扑排序」的神秘面纱,可以说讲的非常详细了。

Ok,我们回到这道题。以题目例2来说:

由于题目本身课程的依赖关系是这么给我们的:[[1,0],[2,0],[3,1],[3,2]] 这种数据格式我们不方便直接使用, 因此我们将其改造成图的一种表示方式邻接矩阵

image.png

可以看到我们浪费了很多空间,这就是邻接矩阵的坏处, 而实际上对于这道题来说,没有必要真的搞一个邻接矩阵,比如这样就行了:

image.png

可以看出空间复杂度要更好一点。

构建矩阵的过程代码:

adjacent = [[] for _ in range(numCourses)]
for cur, pre in prerequisites:
    adjacent[cur].append(pre)

接下来是算法的重点,我们对每一个课程进行一次深度遍历, 并且用visited数组记录每一个课程的访问状态,这样我们可以判断有没有环的存在,如果有环则返回[]

而对于visited,我们使用三色标记法,即没有访问的,访问过但是没有访问完毕的以及完全访问完毕的标记不同颜色。在这里我用0表示没有访问过,1表示访问过但是没有访问完毕,2访问完毕。

DFS 核心逻辑:

def dfs(i):
    # 访问过,还没访问完又回来了,说明有环
    if visited[i] == 1:
        return False
    # 已经完全访问完毕,说明行得通
    if visited[i] == 2:
        return True
    # 遍历前标记1
    visited[i] = 1
    for j in adjacent[i]:
        if not dfs(j):
            return False
    # 遍历后标记2
    visited[i] = 2
    # 为2的都可以加入res了
    res.append(i)
    return True

关键点

  • 拓扑排序

  • 三色标记

代码

class Solution:
    def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
        res = []
        visited = [0] * numCourses
        adjacent = [[] for _ in range(numCourses)]

        def dfs(i):
            if visited[i] == 1:
                return False
            if visited[i
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值