题目:
- 一个机器人位于一个
m x n
网格的左上角 (起始点在下图中标记为“Start”
)。 - 机器人每次只能 向下 或者 向右 移动一步。机器人试图达到网格的右下角(在下图中标记为
“Finish”
)。问总共有多少条不同的路径?
示例:
- 输入: m = 3 , n = 7
- 输出: 28
版本一用深搜:(会超时)
class Solution {
public:
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int uniquePaths(int m, int n) {
return dfs(1, 1, m, n);
}
int dfs(int i, int j, int m, int n){
if(i > m || j > n) return 0; // 越界
if(i == m && j == n) return 1; // 找到一种方法
return dfs(i + 1, j, m, n) + dfs(i, j + 1, m, n);
}
};
版本二:动态规划
- 解题思路:
- 确定dp数组以及下标的含义:
dp[i][j]
表示从 ( 0 , 0 ) (0,0) (0,0) 出发,到 ( i , j ) (i, j) (i,j) 有dp[i][j]
条不同的路径。 - 确定递推公式: 由于题意,只能 向下 或 向右 走,因此可以从两个方向来推导出
dp[i][j]
,即从dp[i - 1][j]
和dp[i][j - 1]
。dp[i - 1][j]
表示从 ( 0 , 0 ) (0,0) (0,0) 到 ( i − 1 , j ) (i - 1, j) (i−1,j) 有多少条路径;dp[i][j - 1]
表示从 ( 0 , 0 ) (0, 0) (0,0) 到 ( i , j − 1 ) (i, j - 1) (i,j−1) 有多少条路径。因此将这两个方向的路径数 相加,即为dp[i][j]
的值。 - dp数组的初始化: 首先
dp[i][0]
一定都是1, 因为从 ( 0 , 0 ) (0, 0) (0,0) 的位置到 ( i , 0 ) (i, 0) (i,0) 的路径只有一条,dp[0][j]
同理。 - 确定遍历顺序: 这里要看一下递推公式
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
,dp[i][j]
都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了。
- 确定dp数组以及下标的含义:
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m, vector<int>(n, 0));
for(int i = 0; i < m; i++) dp[i][0] = 1;
for(int j = 0; j < n; j++) 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];
}
};
时间复杂度:
O
(
m
×
n
)
O(m×n)
O(m×n)
空间复杂度:
O
(
m
×
n
)
O(m×n)
O(m×n)