重要的一点在于:只能向右或向下移动。
这段代码的算法思想是使用**动态规划(Dynamic Programming, DP)**来解决问题。其核心思想是通过将问题分解成更小的子问题,并用一个二维数组来保存这些子问题的解,从而避免重复计算,达到优化时间复杂度的目的。
算法步骤:
-
创建二维数组
dp
:dp[i][j]
表示从起点(左上角)走到网格中位置(i, j)
的不同路径数量。- 首先,定义一个大小为
m x n
的二维数组dp
,用于存储每个位置的路径数量。
-
初始化第一行和第一列:
- 对于第一行的每个位置
(0, j)
,机器人只能从左侧位置走过来,因此到达这些位置的路径数量只能为 1。 - 同理,对于第一列的每个位置
(i, 0)
,机器人只能从上方位置走过来,因此到达这些位置的路径数量也只能为 1。 - 这一步初始化了
dp
数组的边界条件,表示当只能往一个方向(右或下)走时的情况。
- 对于第一行的每个位置
-
填充
dp
数组:- 对于网格中任意位置
(i, j)
,机器人可以从上方(i-1, j)
或左侧(i, j-1)
走过来。 - 因此,当前位置的路径数量为其上方位置和左侧位置的路径数量之和,即:
d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 ] dp[i][j] = dp[i-1][j] + dp[i][j-1] dp[i][j]=dp[i−1][j]+dp[i][j−1] - 通过这个递推公式,逐步计算出每个位置的路径数量。
- 对于网格中任意位置
-
返回结果:
- 最终的结果是右下角位置
dp[m-1][n-1]
的值,它表示从左上角到右下角的不同路径数量。
- 最终的结果是右下角位置
算法思想简要总结:
- 动态规划的核心思想是将一个大问题拆解成若干小问题,利用之前已经计算过的子问题的解来构建新的解,从而避免了重复计算。
- 在本题中,利用二维数组
dp
记录每一步的结果,通过从上到下、从左到右的遍历,逐步得到最终的解。
时间复杂度与空间复杂度:
- 时间复杂度 :
O(m * n)
,我们需要遍历整个m x n
的网格,计算每个位置的路径数量。 - 空间复杂度 :
O(m * n)
,我们使用了一个m x n
的二维数组来存储每个位置的路径数量。
这个算法非常高效,通过动态规划将问题的复杂度降低到了一个可以接受的范围。如果你对任何细节还有疑问,随时告诉我!
java
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for(int i = 0; i < n; ++i) {
dp[0][i] = 1;
}
for(int i = 0; i < m; ++i) {
dp[i][0] = 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];
}
}