题目描述
一个机器人位于一个 m x n
网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:
输入:m = 3, n = 7 输出:28
示例 2:
输入:m = 3, n = 2 输出:3 解释: 从左上角开始,总共有 3 条路径可以到达右下角。 1. 向右 -> 向下 -> 向下 2. 向下 -> 向下 -> 向右 3. 向下 -> 向右 -> 向下
示例 3:
输入:m = 7, n = 3 输出:28
示例 4:
输入:m = 3, n = 3 输出:6
解题思路
题目要求在一个 m x n
的网格中,从左上角到达右下角的所有不同路径数量。每次只能向下或向右移动。
这是一个典型的动态规划问题:
- 状态定义:用
f[i][j]
表示从起点到达网格点(i, j)
的路径数量。 - 状态转移:
- 每个网格点的路径数量等于其上方网格点的路径数量和左侧网格点的路径数量之和,即:f[i][j]=f[i−1][j]+f[i][j−1]f[i][j]=f[i−1][j]+f[i][j−1]
- 初始条件:
- 第一行的所有网格点只能从左侧移动过来,所以路径数量为
1
。 - 第一列的所有网格点只能从上方移动过来,所以路径数量也为
1
。
- 第一行的所有网格点只能从左侧移动过来,所以路径数量为
- 目标值:
f[m-1][n-1]
即为到达右下角网格点的路径数量。
源码实现
class Solution {
public int uniquePaths(int m, int n) {
// 初始化一个 m x n 的二维数组,用于存储路径数量
int[][] f = new int[m][n];
// 第一列的路径数量初始化为 1(只能从上方到达)
for (int i = 0; i < m; ++i) {
f[i][0] = 1;
}
// 第一行的路径数量初始化为 1(只能从左侧到达)
for (int j = 0; j < n; ++j) {
f[0][j] = 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];
}
}
复杂度分析
-
时间复杂度:
- 遍历了整个
m x n
的网格,每个网格点的状态只计算一次。 - 时间复杂度为 O(m×n)O(m×n)。
- 遍历了整个
-
空间复杂度:
- 需要一个
m x n
的二维数组f
存储所有网格点的路径数量。 - 空间复杂度为 O(m×n)O(m×n)。
- 需要一个