1.不同路径
代码:
cpp
class Solution {
public:
int uniquePaths(int m, int n) {
// dp[i][j] 表示从起点走到坐标为i,j的地方的方法数
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];
}
};
思路:
dp数组的含义:从起点走到坐标为i,j的方法数
递推公式:因为只能向右或向下走,所以dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
初始化:因为是由左方的方法数,和上方的方法数推出来的,因此,我们只需要初始化最上方的行,和最左边的列。而我们的dp数组的含义是方法数,因此,它们全部初始化为1.
遍历顺序:从上到下,从左到右
这道题,我还是出错了,虽然我递推公式写对了,但是我在初始化的时候,没有想到我的dp数组表示方法数,我写成了步数。
2.不同路径2
代码:
cpp
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
vector<vector<int>> dp(m,vector<int>(n,0));
// 初始化
for(int i = 0;i < m && obstacleGrid[i][0] == 0;i++){
dp[i][0] = 1;
}
for(int j = 0;j < n && obstacleGrid[0][j] == 0;j++){
dp[0][j] = 1;
}
// 递推公式
for(int i = 1;i < m; i++){
for(int j = 1;j < n; j++){
if(obstacleGrid[i][j] == 0){
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m - 1][n - 1];
}
};
思路:
dp数组的含义:从起点走到坐标为i,j的方法数
递推公式:因为只能向右或向下走,所以dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
初始化:因为是由左方的方法数,和上方的方法数推出来的,因此,我们只需要初始化最上方的行,和最左边的列。而我们的dp数组的含义是方法数,因此,它们全部初始化为1.
遍历顺序:从上到下,从左到右
和上一题的区别主要体现在初始化和递推公式上,在初始化时,如果遇到了障碍,就应该停止初始化(这样没有被初始化的dp元素默认为0种方法);在递推时,加上判断条件,判断我们的目标地点没有障碍时,再进行递推。