一、问题
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?
https://leetcode.cn/problems/unique-paths/description/
二、算法思路
用一个二维数组记录每个格子的路径数,其中第一行和第一列的路径数都是1,因为机器人只能向右或向下移动,所以从起点出发,第一行和第一列的任何一个格子只能通过一种路径到达,即只能一直向右或者一直向下走。所以,第一行和第一列的路径数都是1。
对于其他格子,它的路径数等于它左边格子的路径数加上它上边格子的路径数,即:
dp[i][j] = dp[i-1][j] + dp[i][j-1]
最后返回右下角格子的路径数即可。
Java代码中令第一行和第一列的值为1,其他的行和列使用状态转移方程获得。
C++代码中初始化二维数组的所有元素值为1,所以直接中第二行和第二列开始,使用状态转移方程即可。
三、代码实现
Java
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n]; //二维数组,初始默认值为0
for (int i = 0; i < m; i++) { //第1列的元素值为1
dp[i][0] = 1;
}
for (int j = 0; j < n; j++) { //第1行的元素值为1
dp[0][j] = 1;
}
for (int i = 1; i < m; i++) { //计算其他行和列的值
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
}
C++
class Solution {
public:
int uniquePaths(int m, int n) {
// 创建二维数组 dp,用于记录每个格子的路径数,初始化元素值为1
vector<vector<int>> dp(m, vector<int>(n, 1));
// 计算 dp[i][j] 的值
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1]; // 返回终点的路径数
}
};
复杂度分析
- 时间复杂度: O ( m n ) O(mn) O(mn)
- 空间复杂度: O ( m n ) O(mn) O(mn)