题目描述
思路解析动画文字版
记住这一句:入度0 = 现在就能学;学完一门就给后续课「松绑」。下面一步步建图再排序。
先把 6 门课 0~5 摆成 6 个节点,入度(还有几门没学的先修课)都标 0。接下来逐条读先修关系,连出有向边。
读到 [1, 0]:想学课 1,必须先学课 0。高亮这两门课——课 0 要排在课 1 前面。
连一条有向边 0→1(先学 0 才能学 1)。课 1 又多了一门没学的先修课,入度 +1(看它上方)。
读到 [2, 0]:想学课 2,必须先学课 0。高亮这两门课——课 0 要排在课 2 前面。
连一条有向边 0→2(先学 0 才能学 2)。课 2 又多了一门没学的先修课,入度 +1(看它上方)。
读到 [3, 1]:想学课 3,必须先学课 1。高亮这两门课——课 1 要排在课 3 前面。
连一条有向边 1→3(先学 1 才能学 3)。课 3 又多了一门没学的先修课,入度 +1(看它上方)。
读到 [3, 2]:想学课 3,必须先学课 2。高亮这两门课——课 2 要排在课 3 前面。
连一条有向边 2→3(先学 2 才能学 3)。课 3 又多了一门没学的先修课,入度 +1(看它上方)。
读到 [4, 3]:想学课 4,必须先学课 3。高亮这两门课——课 3 要排在课 4 前面。
连一条有向边 3→4(先学 3 才能学 4)。课 4 又多了一门没学的先修课,入度 +1(看它上方)。
读到 [5, 4]:想学课 5,必须先学课 4。高亮这两门课——课 4 要排在课 5 前面。
连一条有向边 4→5(先学 4 才能学 5)。课 5 又多了一门没学的先修课,入度 +1(看它上方)。
建图完成。开始 Kahn 拓扑排序:看节点上方入度,课 0 入度为 0(没有任何先修课要先学)→ 入队,现在就能学。
队首课 0 出队,现在去学它,追加到学习顺序:[0]。学完后给它解锁的后续课松绑。
学完课 0 后,它解锁的后续课 1 少了一门待学先修课:入度减 1,变为 0——降到 0,马上可以学。
课 1 的入度降到 0(先修课都学完了)→ 入队,等待安排。
学完课 0 后,它解锁的后续课 2 少了一门待学先修课:入度减 1,变为 0——降到 0,马上可以学。
课 2 的入度降到 0(先修课都学完了)→ 入队,等待安排。
队首课 1 出队,现在去学它,追加到学习顺序:[0,1]。学完后给它解锁的后续课松绑。
学完课 1 后,它解锁的后续课 3 少了一门待学先修课:入度减 1,变为 1,还有别的先修课没学完,暂不入队。
队首课 2 出队,现在去学它,追加到学习顺序:[0,1,2]。学完后给它解锁的后续课松绑。
学完课 2 后,它解锁的后续课 3 少了一门待学先修课:入度减 1,变为 0——降到 0,马上可以学。
课 3 的入度降到 0(先修课都学完了)→ 入队,等待安排。
队首课 3 出队,现在去学它,追加到学习顺序:[0,1,2,3]。学完后给它解锁的后续课松绑。
学完课 3 后,它解锁的后续课 4 少了一门待学先修课:入度减 1,变为 0——降到 0,马上可以学。
课 4 的入度降到 0(先修课都学完了)→ 入队,等待安排。
队首课 4 出队,现在去学它,追加到学习顺序:[0,1,2,3,4]。学完后给它解锁的后续课松绑。
学完课 4 后,它解锁的后续课 5 少了一门待学先修课:入度减 1,变为 0——降到 0,马上可以学。
课 5 的入度降到 0(先修课都学完了)→ 入队,等待安排。
学课 5,加入学习顺序。所有 6 门课都已出队、入度全清零——拓扑排序完成!出队顺序 [0,1,2,3,4,5] 就是一个合法学习顺序,即答案。
边界先想清:无环必有解,有环返回空。
两个高频追问。
参考代码
def findOrder(numCourses, prerequisites): g = [[] for _ in range(numCourses)] indeg = [0] * numCourses for a, b in prerequisites: # 先学 b 才能学 a g[b].append(a) indeg[a] += 1 q = deque([c for c in range(numCourses) if indeg[c] == 0]) order = [] while q: c = q.popleft(); order.append(c) for nb in g[c]: indeg[nb] -= 1 if indeg[nb] == 0: q.append(nb) return order if len(order) == numCourses else []复杂度
- 时间:O(V + E),V=课程数,E=先修关系数;每门课入队出队一次、每条边松弛一次
- 空间:O(V + E),邻接表存边 + 入度数组 + 队列
易错点
面试追问把动画讲成自己的话
追问课程表 I(只问能不能学完)和课程表 II(要输出顺序)有什么区别?
追问除了 BFS(Kahn),还能怎么做拓扑排序?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
冗余连接
LeetCode 684 · 中等 · 沿着 图 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题