62.不同路径
题目链接 lc62
思路:
动态规划:
1、确定dp数组以及其下标含义
dp[i][j]: 表示从(0, 0)出发,到达[i][j]有dp[i[[j]种组合
2、确定递推公式
想要求dp[i][j],只能有两个方向来推导出来,即dp[i - 1][j] 和 dp[i][j - 1]。
此时在回顾一下 dp[i - 1][j] 表示啥,是从(0, 0)的位置到(i - 1, j)有几条路径,dp[i][j - 1]同理。
那么很自然,dp[i][j] = dp[i - 1][j] + dp[i][j - 1],因为dp[i][j]只有这两个方向过来。
3、dp数组初始化
首先dp[i][0]一定都是1,因为从(0, 0)的位置到(i, 0)的路径只有一条,那么dp[0][j]也同理
4、确定遍历顺序
公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是从其上方和左方推导而来,那么从左到右一层一层遍历就可以了。
5、打印dp数组,
class Solution {
public:
int uniquePaths(int m, int n) {
//1、确定dp[i][j]的含义: 在i,j这个位置的路径数
//2、确定递推公式:dp[i][j] = dp[i][j-1] + dp[i-1][j]
//3、dp数组初始化:dp[i][0] = 1列的路径数都是1, dp[0][j] = 1, 行的路径都是1
//4、确定变量顺序,依次上到下,左到右
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][j-1] + dp[i-1][j];
cout << dp[i][j] << endl;
}
}
return dp[m-1][n-1];
}
};
时间复杂度:O(m × n)
空间复杂度:O(m × n)
总结: 动态规划类经典题目,这种还是比较好思考的,但是要注意在解题过程中应该按照动态规划步骤一步一步进行。
63. 不同路径 II
思路:动态规划
这道题和上面一道题很类似,但是多了有障碍的情况,一时间拿到不知道怎么上手。但是通过查看题解和视频,还是很简单的
1、确定dp数组以及其下标含义
dp[i][j] 到达(i, j)位置的路径数
2、确定递推公式
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
这里还是和上面相同,但是在循环的时候,需要加上判断
3、初始化
这里是最重要的一点,首先在上面那题的判断中,第一行或者第一列全部初始化为1,而这道题则是遇到障碍后,后面的都不应该初始化,所以在进行初始化的时候,增加判断条件,遇到障碍结束赋值。
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;
4、确定遍历顺序
和上一题一样,对应从上到下,从左到右即可,两层for循环
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
// dp[i][j]: 到达i,j位置的路径总和
// 确定递推公式;
// dp数组初始化:如果数组
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] == 1) {
continue;
}
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
};
总结: 还是比较容易遇到问题的一类题,动态规划这几个步骤一定要想清楚,每一步是什么情况都要知道,最好是模拟打印出dp数组,方便debug。