一、题目描述
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?
示例 1:
输入:m = 3, n = 7 输出:28
示例 2:
输入:m = 3, n = 2 输出:3
解释:从左上角开始,总共有 3 条路径可以到达右下角。
-
向右 -> 向下 -> 向下
-
向下 -> 向下 -> 向右
-
向下 -> 向右 -> 向下
二、思路及回顾
由于机器人只能向下和向右移动,所以二维数组中第一行和第一列永远只有一种走法
假设终点在第二行第二列(图中鼠标),通过推导我们可以得知有两种走法,用二维数组表示这两种走法可以得出,假设终点用f[ i ][ j ],它只能在终点的左边f[ i ][ j-1 ](即第二行第一列)或者终点上边f[ i-1 ][ j ](即第一行第二列)进入终点,则这两种走法就是该点的两种路径,再看看其他的点也满足这条件:不管怎么走,最后的路径都是在该点的左边或是上边进入。
由此可以推导出状态方程:f[ i ][ j ] = f[ i ][ j-1 ] + f[ i-1 ][ j ]
现在定义 js二维数组可以用数组方法
const f = new Array(m).fill(0).map(() => new Array(n).fill(0));
解动态规划的步骤
1. 根据重叠问题定义状态
2. 寻找最优子结构推导状态方程
3. 确定dp初始状态
4. 确定输出值
三、代码展示
var uniquePaths = function(m, n) {
const f = new Array(m).fill(0).map(() => new Array(n).fill(0)); // 初始化数组
// 初始化行
for(let i = 0; i < m; i++) {
f[i][0] = 1;
}
// 初始化列
for(let j = 0; j < n; j++) {
f[0][j] = 1
}
for(let i = 1; i < m; i++) {
for(let j = 1; j < n; j++) {
f[i][j] = f[i][j-1] + f[i-1][j] // 确定状态方程
}
}
return f[m-1][n-1] // 确定最终值
}