题目描述
思路解析动画文字版
最直接的想法是从起点递归,每格往右、往下各试一次,数到终点的路径条数。可同一个格子会被无数条前缀重复访问,「从这格到终点有几条路」被反复重算,网格一大就指数爆炸。
转折:用 dp[i][j] 记「走到这格有几条路」,每格只算一次。一个格子只能从上面或左边来,所以 dp[i][j] = dp[i−1][j] + dp[i][j−1]。遇到障碍,谁也站不上去,dp 直接置 0——它就不会再把路径数传给右边和下边,那些经过障碍的路自动被掐断。
建表 · 起点 dp[0][0]=1:建一张 3×3 的 dp 表,行列数全程不变。起点不是障碍,站在那儿本身就算 1 条路,先填 dp[0][0]=1。其余先空着,按从上到下、从左到右逐格填。
第一行 · 只能向右:第一行头顶没有格子,只能一路向右走过来。这一行没障碍,所以全是 1,就是一条直路。
第一列 · 只能向下:第一列同理,只能一路向下,也没障碍,也全是 1。现在边界铺好了,开始填中间。
障碍格 (1,1) = 0:轮到正中央,它是障碍。这里走障碍分支:不算上+左,直接把 dp 记成 0——没有任何走法能合法停在障碍上。这个 0 待会儿会传给它右边和下边。
填 (1,2) · 上1 + 左0:这格不是障碍,正常算上+左:上面是 1,左边是障碍传来的 0,相加只剩 1 条路。障碍的 0 在这里第一次起作用,把原本能从左边来的路抹掉了。
填 (2,1) · 上0 + 左1:这格也算上+左:上面又是障碍传来的 0,左边是 1,结果 1 条路。可以看到障碍的 0 同时切断了右边和下边两个方向。
右下角 · 上1 + 左1:终点 = 上面 1 + 左边 1 = 2。这正是绕过中央障碍的那 2 条路:贴上边绕一条、贴下边绕一条。
答案:右下角 dp[2][2] = 2 就是答案。整张表填完,障碍那格的 0 把所有穿过它的路都拦住了。
网格 DP 里碰到不可用的格子,把它的 dp 置 0(计数题)或置无穷(最值题),它就不会再把值传给右边、下边——障碍、陷阱、禁区都这么处理。
雷区实演 · 起点就是障碍:把起点换成障碍试一下:dp[0][0] 一开始就该是 0,不能写 1。0 一路向右、向下传,整张表全是 0,最后答案是 0。这就是为什么必须先特判起点。
几个高频追问,记住答法。
迁移阶梯:把这题练到能复述后,去网格 DP 专题里迁移:状态定义照搬,只改边界和「障碍清零」这一笔。卡住就问问 AI 助教,或进通关训练实战一遍。
边界三连:边界三连:起点障碍、终点障碍、单格网格,极端输入先各过一遍。
参考代码
class Solution: def uniquePathsWithObstacles(self, grid): m, n = len(grid), len(grid[0]) dp = [[0] * n for _ in range(m)] if grid[0][0] == 1: return 0 dp[0][0] = 1 for i in range(m): for j in range(n): if grid[i][j] == 1: dp[i][j] = 0 continue if i: dp[i][j] += dp[i - 1][j] if j: dp[i][j] += dp[i][j - 1] return dp[m - 1][n - 1]复杂度
- 时间复杂度:O(m×n),每格只算一次「上+左」,共 m×n 格
- 空间复杂度:O(m×n),一张 m×n 的 dp 表,可压成一行 O(n)
可套用的代码模板
记住三笔:先特判起点不可用、障碍格清零跳过、其余「上+左」累加。把「相加」换成 min/max + 当前格代价,就是带障碍的最小/最大路径和。
# 凡是「网格里从左上走到右下、含禁区」的题都能套dp = [[0]*n for _ in range(m)]if 起点不可用: return 0 # 先特判起点dp[0][0] = 起点初值for i in range(m): for j in range(n): if 不可用(i, j): # 障碍清零跳过 dp[i][j] = 0; continue if i: dp[i][j] += dp[i-1][j] # 上 if j: dp[i][j] += dp[i][j-1] # 左return dp[m-1][n-1]易错点
面试追问把动画讲成自己的话
追问和不同路径 I 相比只改了什么?
追问能优化空间吗?
追问起点或终点是障碍会怎样?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。再去主线里挑下一道练手。
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题