62.不同路径
题解:本题使用动态规划法,依旧是动态规划五部曲
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数组的初始化
初始化代码:
for(int i = 0; j < m; i++) dp[i][0] = 1;
for(int j = 0; j < n; j++) dp[0][j] = 1;
4.确定遍历顺序
从递推公式就可以看出dp[i][j]都是从上方和左方推导出来,所以是从左上开始推导
5.举例推导dp数组
打印dp数组即可
C语言代码如下:
int **initDP(int m, int n) {
int **dp = (int**)malloc(sizeof(int *) * m);
int i,j;
for(i = 0; i < m; ++i) {
dp[i] = (int *)malloc(sizeof(int) * n);
}
for(i = 0; i < m; ++i)
dp[i][0] = 1;
for(j = 0; j < n; ++j)
dp[0][j] = 1;
return dp;
}
int uniquePaths(int m, int n){
int **dp = initDP(m,n);
int i,j;
for(i = 1; i < m; ++i) {
for(j = 1; j < n; ++j) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
int result = dp[m-1][n-1];
free(dp);
return result;
}
63.不同路径II
题目链接:63. 不同路径 II - 力扣(LeetCode)
1.确定dp数组以及下标含义
dp[i,j]代表从(0,0)出发,到(i,j)有dp[i][j]条不同路径
2.确定递推公式
与62题相似dp[i - 1][j] 和 dp[i][j - 1]。
if (obstacleGrid[i][j] == 0) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
3.dp数组如何初始化
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;
4.确定遍历顺序
从递推公式就可以看出dp[i][j]都是从上方和左方推导出来,所以是从左向右遍历
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];
}
}
5.举例推导dp数组
打印dp数组
C语言代码如下:
//初始化dp数组
int **initDP(int m, int n, int** obstacleGrid) {
int **dp = (int**)malloc(sizeof(int*) * m);
int i, j;
//初始化每一行数组
for(i = 0; i < m; ++i) {
dp[i] = (int*)malloc(sizeof(int) * n);
}
//先将第一行第一列设为0
for(i = 0; i < m; ++i) {
dp[i][0] = 0;
}
for(j = 0; j < n; ++j) {
dp[0][j] = 0;
}
//若碰到障碍,之后的都走不了。退出循环
for(i = 0; i < m; ++i) {
if(obstacleGrid[i][0]) {
break;
}
dp[i][0] = 1;
}
for(j = 0; j < n; ++j) {
if(obstacleGrid[0][j])
break;
dp[0][j] = 1;
}
return dp;
}
int uniquePathsWithObstacles(int** obstacleGrid, int obstacleGridSize, int* obstacleGridColSize){
int m = obstacleGridSize, n = *obstacleGridColSize;
//初始化dp数组
int **dp = initDP(m, n, obstacleGrid);
int i, j;
for(i = 1; i < m; ++i) {
for(j = 1; j < n; ++j) {
//若当前i,j位置有障碍
if(obstacleGrid[i][j])
//路线不同
dp[i][j] = 0;
else
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
//返回最后终点的路径个数
return dp[m-1][n-1];
}