62.不同路径
https://leetcode-cn.com/problems/unique-paths
题目描述
方法 1:递归(TLE)
思路
首先是直觉的递归法。
在每个格子我们都有两个选择:
向右走、向下走如果走到了网格最右侧的那一列,我们就只剩下
向下走这个选项如果走到了网格最底下的那一行,我们就只剩下
向右走这个选项所以在每个格子做选择之前,先要判断能不能向右/向下走
等走到最后一个格子,在这个格子我们既不能向右也不能向下,就在记录上加一
代码
JavaScript Code
更简洁的递归版:
JavaScript Code
复杂度分析
时间复杂度:$O(2^max(m, n))$,2 是递归树的最大分支数,因为在每个函数中都有两次递归调用,指数部分是树的最大深度。
空间复杂度:$O(max(m, n))$,递归树的最大深度。
方法 2:动态规划
思路
我们的目标是走到网格右下角的格子,不妨假设我们已经走到了这个格子,那往前推一步,走到这个格子之前我们在哪呢?只能是它左边或者上方的格子。
假设我们已经知道了有多少条路径可以走到它左边的格子,用
F(left)来表示;假设我们也已知道了有多少条路径可以走到它上方的格子,用
F(top)来表示;
那我们很容易就能算出,要走到右下角的格子,一共有 F(bottomRight) = F(left) + F(top) 条路径。
我们可以从右下角的格子一直往前推,计算每个格子的状态 F(cell) = F(left) + F(top)。直到,退到起点,因为我们已经站在起点了,也就是说只有一条路,所以 F(topLeft) = 1。
现在我们再把这个过程反过来,从起点开始,一直往右下角的格子前进,一路算出走到每个格子有多少条路径 F(cell),最终就可以得到我们想要的结果 F(bottomRight) 了。
因为要记录每个格子的状态,所以需要一个二维数组

代码
TypeScript Code
Python Code
复杂度分析
时间复杂度:$O(m*n)$。
空间复杂度:$O(m*n)$。
动态规划(空间优化版)
思路
因为每个格子只依赖它左边和上边的格子的状态,所以我们没必要用二维数组来存储整个网格的状态,只需要两个一维数组:一个存上一行格子的状态,一个存当前行格子的状态,然后在遍历的过程中更新这两个数组就好了。
代码
TypeScript Code
复杂度分析
时间复杂度:$O(m*n)$。
空间复杂度:$O(n)$。
相似题目 - 63. 不同路径 II
https://leetcode-cn.com/problems/unique-paths-ii/
思路
跟 62 题差不多,只是如果当前格子有障碍的话,就把 dp[i][j] 重置为 0,说明此路不通。
代码
动态规划:
JavaScript Code
空间优化:
JavaScript Code
Last updated
Was this helpful?