彦祖天天见
62.不同路径
一个机器人位于一个 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
提示:
1 <= m, n <= 100
- 题目数据保证答案小于等于
2 * 109
这道题目适合用动态规划的思想来解决,进行动态规划的五部曲
第一步:确定dp数组及下标的含义
由于是一个m*n的网格,我们用一个二维数组来存储结果,其中dp【i】【j】表示从起点0,0到【i】【j】坐标有dp【i】【j】种不同的路径。
第二步:确定递推公式
题目中指出机器人只能往两个方向走分别是向右和向上,所以在某一个网格的路径dp【i】【j】,机器人只能由dp【i-1】【j】和dp【i】【j-1】过来,将这两个方向相加就是dp【i】【j】的不同路径和了。所以递推公式就是:
dp[i][j]=dp[i-1][j]+dp[i][j-1];
第三步:初始化
由于机器人是在左上角起步的,所以他可以到达任意一个网格,先将所有网格初始化为1;
第四步:确定遍历顺序
当前网格是由左边和上边推导而来,所以是从前往后遍历。
第五步:打印并纠错dp数组
这里放张图更加明显
完整代码如下:
class Solution {
public:
int uniquePaths(int m, int n) {
//dp[i][j]表示从0,0到i,j的不同路径,是dp[i-1][j]+dp[i][j-1]的和
vector<vector<int>> dp(m,vector<int>(n,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];
}
};
63.不同路径Ⅱ
一个机器人位于一个 m x n
网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1
和 0
来表示。
示例 1:
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2
条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
示例 2:
输入:obstacleGrid = [[0,1],[0,0]] 输出:1
这一题和上一题的不同就是增加了障碍物,当遇到障碍物时是无法前进的。但整体思路是和上题一致的,将初始化和遍历dp数组时的条件修改即可。
初始化:
如果我们一直往下走或者一直往右走,那么走过的网格路径数都是1,这时就完成了初始化,便于其他的网格根据特性进行递推。当往下或往右时遇到了障碍物就无法前进了,所以障碍物 包括它之后的网格都无法前往,就置为0。
遍历:
同理,遇到障碍物时我们就跳过这个障碍物,当障碍物在我们下方时,就往右边走,当障碍物在我们右边时,我们就往下走。所以可以不进行特殊处理,遇到就跳过本次循环。
代码如下:
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
//获取数组的行和列
int m =obstacleGrid.size();
int n=obstacleGrid[0].size();
//初始化dp数组
vector<vector<int>> dp(m,vector<int>(n,0));
//如果边界上没有障碍物就初始化为1
for(int i=0;i<m && obstacleGrid[i][0]==0;i++) dp[i][0] = 1;
for(int i=0;i<n && obstacleGrid[0][i]==0;i++) dp[0][i] = 1;
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
//如果有障碍物就跳过
if(obstacleGrid[i][j]==1) continue;
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
};