多维动态规划题解——不同路径【LeetCode】记忆化搜索
62. 不同路径
一、算法逻辑(逐步思路)
❓ 题目描述:
机器人位于一个 m × n
的网格左上角 (0, 0),只能向右或向下移动,每次一步。问到达右下角 (m-1, n-1) 有多少条不同路径?
✅ 解题思路(DFS + 记忆化)
1. 状态定义:
dfs(i, j) 表示从 (0, 0) 到达 (i, j) 的路径数
2. 状态转移方程:
- 机器人只能从 上方 (i-1, j) 或 左边 (i, j-1) 走到
(i, j)
,所以:
dfs(i, j) = dfs(i-1, j) + dfs(i, j-1)
3. 终止条件:
- 如果某个坐标在第一行或第一列(
i==0
或j==0
),说明只能沿一个方向走,所以路径数为 1; - 如果走到负数坐标(越界),返回 0(安全边界检查,但实际上不会触发);
4. 初始调用:
- 我们要求的是从
(0, 0)
到(m-1, n-1)
的路径数,所以调用dfs(m-1, n-1)
。
5. 使用 @cache
做记忆化优化,避免重复子问题导致的指数级递归。
二、算法核心点
✅ 核心思想:二维递归建模 + 缓存子问题(记忆化)
- 本质上是一个二维 DP 问题,用 DFS 来实现自顶向下的解法;
- 每个位置的路径数 = 左边格子路径数 + 上边格子路径数;
- 使用
@cache
缓存递归结果,避免重复计算,极大提升性能。
class Solution:def uniquePaths(self, m: int, n: int) -> int:@cachedef dfs(i:int, j:int) -> int:if i == 0 or j == 0:return 1if i<0 or j<0:return 0return dfs(i-1, j)+dfs(i, j-1)return dfs(m-1, n-1)
三、复杂度分析
- 时间复杂度:O(m × n)
-
- 每个状态
(i, j)
只计算一次,最多 m×n 种状态。
- 每个状态
- 空间复杂度:O(m × n)
-
- 记忆化缓存占用空间;
- 递归栈最大深度为
m + n
总结表:
维度 | 内容 |
✅ 思路逻辑 | 每个格子只能从上或左来,递归地组合路径数 |
✅ 核心技巧 | DFS 建模 + 记忆化;基础的二维路径 DP 问题 |
✅ 时间复杂度 | O(m × n),每个状态只算一次 |
✅ 空间复杂度 | O(m × n),缓存 + 递归栈深度 |
✅ 拓展建议
- ✅ 更快的迭代写法(自底向上 DP 表),也可将空间优化为 O(n);
- ✅ 组合数学解法:路径总数为组合数
C(m + n - 2, m - 1)
,最快速.