作者:MJ昊
公众号:程序猿的编程之路
今天是 昊 的算法之路第13天,今天分享的是LeetCode第62题不同路径的解题思路。这是一道中等难度的动态规划题目,考察路径规划的优化策略与状态转移的理解。
题目描述简要回顾
给定一个 m x n 的网格,从 左上角 (0, 0) 出发,每次只能向 右 或 下 移动一步,目标是到达 右下角 (m-1, n-1)。
问有多少条不同的路径可以达到终点。
解题思路
方法:递归 + 缓存(记忆化搜索)
-
递归思路:
-
每次从当前位置
(cur_m, cur_n)出发,有两种选择:- 向下移动:到
(cur_m + 1, cur_n) - 向右移动:到
(cur_m, cur_n + 1)
- 向下移动:到
-
当到达最后一行或最后一列时,只剩下一条路径,因此直接返回 1。
-
-
使用缓存(Memoization) :
- 用缓存记录计算过的路径数量,避免重复计算,从而减少时间复杂度。
- 缓存的键为
"cur_m_cur_n",表示从(cur_m, cur_n)出发的路径数量。
代码实现:
var uniquePaths = function (m, n) {
const cache = {};// 初始化缓存
const maxPath = (m, n, cur_m, cur_n) => {
if (cur_m === m - 1 || cur_n === n - 1) return 1; // 到达最后一行或最后一列
const params = `${cur_m}_${cur_n}`// 缓存键
if (cache[params] !== undefined) return cache[params]// 若已有缓存,直接返回
// 递归计算向下和向右的路径数量之和
cache[params] = maxPath(m, n, cur_m + 1, cur_n) + maxPath(m, n, cur_m, cur_n + 1)
return cache[params]
}
return maxPath(m, n, 0, 0)// 从 (0, 0) 出发
};
复杂度分析##
-
时间复杂度:O(m * n)
- 每个位置的路径数量最多只计算一次,因此时间复杂度为 O(m * n)。
-
空间复杂度:O(m * n)
- 使用缓存存储每个位置的路径数量,缓存大小与网格大小相关。
总结
这道题展示了 递归 和 缓存(记忆化搜索) 的结合应用。通过缓存避免重复计算,提高了算法的效率。如果输入规模较大,可以尝试 动态规划 方法进一步优化代码,避免递归调用的开销。