题目描述
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
问总共有多少条不同的路径?
例如,上图是一个7 x 3 的网格。有多少可能的路径?
说明:m 和 n 的值均不超过 100。
示例 1:
输入: m = 3, n = 2
输出: 3
解释:
从左上角开始,总共有 3 条路径可以到达右下角。
1. 向右 -> 向右 -> 向下
2. 向右 -> 向下 -> 向右
3. 向下 -> 向右 -> 向右
示例 2:
输入: m = 7, n = 3
输出: 28
思路
(1)确定状态
若即Finish位置为(m-1, n-1),则最后一步有两种情况走到(m-2, n-1)或者(m-1, n-2)。
而子问题就可以划分为,如果机器人有X种方式从start走到(m-2, n-1),有Y种方式走到(m-1, n-2),则机器人有X+Y种方式走到(m-1, n-1)。
这里为什么能用加法,因为机器人只能向下或者向右,所以必定没有重复和遗漏。
这里如何确定要开一维数组还是二维数组,看要求中有几个变量,本题求有几种方式从左上角走到(m-1, n-1),有两个变量所以开二维数组。
状态:设f[i][j]为机器人有多少种方式从左上角走到(i, j)。
(2)状态方程
对于任意一个格子(i, j)
f[i][j] = f[i-1][j] + f[i][j-1];
(3)初始条件和边界条件
初始条件:f[0][0] = 1,因为机器人只有一种方式到左上角
边界情况:i=0或者j=0,则前一步只能有一个方向过来,即f[i][j]=1
(4)计算顺序
f[0][0] = 1;
计算第0行:f[0][0],f[0][1],…,f[0][n-1]
计算第1行:f[1][0],f[1][1],…,f[1][n-1]
…
计算第m-1行,f[m-1][0],f[m-1][1],…,f[m-1][n-1]
时间复杂度:O(MN), 空间复杂度O(MN)
代码实现
class Solution {
public:
int uniquePaths(int m, int n) {
// 开数组
vector<vector<int>> f(m, vector<int>(n));
// 初始条件
f[0][0] = 1;
// 边界条件
for (int i = 0; i < n; i++)
f[0][i] = 1;
for (int i = 0; i < m; i++)
f[i][0] = 1;
// 状态方程:按一行行来计算
for (int i = 1; i < m; i++)
for (int j = 1; j < n; j++)
f[i][j] = f[i-1][j] + f[i][j-1];
return f[m-1][n-1];
}
};