题目描述
思路解析动画文字版
记住「到终点就存一份、每个邻居 push 进去递归再 pop 出来」,下面逐帧套它。
先看清这张图:节点 0 是起点(紫色)、节点 5 是终点(绿色)。箭头是有向边,例如 0 能到 1 和 2,1 能到 3 和 4。无环,所以一路往下走不会回到走过的点。
把起点 0 放进当前路径,从 0 开始 DFS。当前路径只有 [0]。0 不是终点,接下来逐个试它的邻居 1、2。
从 0 沿边深入到邻居 1:把 1 压进当前路径,现在路径是 0 → 1。继续从 1 往它的邻居走。
从 1 沿边深入到邻居 3:把 3 压进当前路径,现在路径是 0 → 1 → 3。继续从 3 往它的邻居走。
从 3 沿边深入到邻居 5:把 5 压进当前路径,现在路径是 0 → 1 → 3 → 5。它正是终点,下一步就该记一条。
走到了终点 5!当前路径是 0 → 1 → 3 → 5。把它复制一份存进答案(整条路径变绿),这是第 1 条。然后返回,去试别的岔路。
从 5 这条分支回来了,把 5 弹出当前路径,回退到 3,路径缩回 0 → 1 → 3。3 的邻居都试完了,再往上回退。
从 3 这条分支回来了,把 3 弹出当前路径,回退到 1,路径缩回 0 → 1。1 还有没试过的邻居,接着试下一个。
从 1 沿边深入到邻居 4:把 4 压进当前路径,现在路径是 0 → 1 → 4。继续从 4 往它的邻居走。
从 4 沿边深入到邻居 5:把 5 压进当前路径,现在路径是 0 → 1 → 4 → 5。它正是终点,下一步就该记一条。
走到了终点 5!当前路径是 0 → 1 → 4 → 5。把它复制一份存进答案(整条路径变绿),这是第 2 条。然后返回,去试别的岔路。
从 5 这条分支回来了,把 5 弹出当前路径,回退到 4,路径缩回 0 → 1 → 4。4 的邻居都试完了,再往上回退。
从 4 这条分支回来了,把 4 弹出当前路径,回退到 1,路径缩回 0 → 1。1 的邻居都试完了,再往上回退。
从 1 这条分支回来了,把 1 弹出当前路径,回退到 0,路径缩回 0。0 还有没试过的邻居,接着试下一个。
从 0 沿边深入到邻居 2:把 2 压进当前路径,现在路径是 0 → 2。继续从 2 往它的邻居走。
从 2 沿边深入到邻居 4:把 4 压进当前路径,现在路径是 0 → 2 → 4。继续从 4 往它的邻居走。
从 4 沿边深入到邻居 5:把 5 压进当前路径,现在路径是 0 → 2 → 4 → 5。它正是终点,下一步就该记一条。
走到了终点 5!当前路径是 0 → 2 → 4 → 5。把它复制一份存进答案(整条路径变绿),这是第 3 条。然后返回,去试别的岔路。
从 5 这条分支回来了,把 5 弹出当前路径,回退到 4,路径缩回 0 → 2 → 4。4 的邻居都试完了,再往上回退。
从 4 这条分支回来了,把 4 弹出当前路径,回退到 2,路径缩回 0 → 2。2 的邻居都试完了,再往上回退。
从 2 这条分支回来了,把 2 弹出当前路径,回退到 0,路径缩回 0。0 的邻居都试完了,再往上回退。
DFS 全部跑完,回溯到最后路径只剩起点 [0](dfs(0) 结束后不再用它)。一共找到 3 条从 0 到 5 的路径:0→1→3→5、0→1→4→5、0→2→4→5。回头看,我们就是一路深入、到终点存一份、回溯换岔路,把每条路都不重不漏地走了一遍。
边界:两点一条路;0 直达终点立即记;共用节点的多条路都要枚举。
两个追问:可用 BFS 存路径;复杂度被输出量(可能指数级)主导,无法更优。
参考代码
from typing import Listclass Solution: def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]: ans = [] path = [0] target = len(graph) - 1 def dfs(u: int) -> None: if u == target: ans.append(path[:]) return for v in graph[u]: path.append(v) dfs(v) path.pop() dfs(0) return ans复杂度
- 时间:O(2^n · n),最坏情况(每个点都能到后面所有点)路径条数可达 2^(n−1) 量级,每条路径长 O(n)、复制也要 O(n);所以由输出规模主导
- 空间:O(n),不算答案本身,递归栈深度和 path 长度都是 O(n);DAG 无环,不需要 visited 数组
易错点
面试追问把动画讲成自己的话
追问这题能用 BFS 吗?
追问为什么时间复杂度看起来很大却没法更优?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
找到最终的安全状态
LeetCode 802 · 中等 · 沿着 图论套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题