LeetCode91 - 不同路径
📝 题目描述
题目链接:不同路径
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例:
1 | 示例 1: |
提示:
1 <= m, n <= 100题目数据保证答案小于等于 2 * 10^9
💡 解题思路
方法一:动态规划
我们用 f(i,j) 表示从左上角走到 (i,j) 的路径数量,其中 i 和 j 的范围分别是 [0,m) 和 [0,n)。
由于我们每一步只能从向下或者向右移动一步,因此要想走到 (i,j),如果向下走一步,那么会从 (i−1,j) 走过来;如果向右走一步,那么会从 (i,j−1) 走过来。因此我们可以写出动态规划转移方程:
需要注意的是,如果 i=0,那么 f(i−1,j) 并不是一个满足要求的状态,我们需要忽略这一项;同理,如果 j=0,那么 f(i,j−1) 并不是一个满足要求的状态,我们需要忽略这一项。
初始条件为 f(0,0)=1,即从左上角走到左上角有一种方法。
最终的答案即为 f(m−1,n−1)。
由于当前格子的路径数只依赖于正上方和左侧的格子,我们在遍历时,其实只需要保留“当前行”和“上一行”的数据。进一步压缩,我们只需要一个长度为 n 的一维数组就能完成状态滚动更新。
方法二:组合数学
机器人总共需要移动的步数是固定的:向下走 步,向右走 步,总共需要走 步。
问题就转化为了:在总共 步中,选出 步向下的方案数是多少?
公式即为求组合数 :
在代码实现时,唯一的难点是防止连乘时发生整型溢出。我们可以一边乘一边除,并使用 long long 来存储中间变量。
这里不必担心发生无法整除的现象,任意 个连续自然数的乘积,一定能被 ( 的阶乘)整除。
🔧 代码实现
1、动态规划
1 | class Solution { |
2、组合数学
1 | class Solution { |
📊 复杂度分析
1、动态规划
- 时间复杂度:,需要遍历整个网格。
- 空间复杂度:,只用到了一个长度为 的一维数组。
2、组合数学
- 时间复杂度:,只需要一个简单的循环,循环次数为 和 中较小的那一个。
- 空间复杂度:,只需要常数级变量。
🎯 总结
- 核心思想:记住动态规划的方法,以及优化成一维数组的思路。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 很多时候不懂事!