摘要
本文主要介绍了LeetCode动态规划的几个题目,具体包括62.不同路径、63. 不同路径 II。这些题目有助于我们更好地理解动态规划中dp数组初始化的重要性。
1、62.不同路径
1.1 思路
-
dp数组以及下标的含义:机器人到达i x j网格的右下角有dp[i][j]条不同的路径 -
递推公式:
- 到达i, j-1网格,有
dp[i][j-1]条不同的路径,到达i-1, j网格,有dp[i-1][j]条不同的路径 - 所以
dp[i][j] = dp[i][j-1] + dp[i-1][j]
- 到达i, j-1网格,有
-
dp数组如何初始化:dp[i][0] = 1; dp[0][j] = 1 -
dp数组遍历顺序:dp[i]是依赖dp[i][j-1] 和 dp[i-1][j],所以是从上到下,从左到右 -
打印
dp数组
1.2 代码
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for(int i=0; i<m; i++) {
for(int j=0; j<n; j++) {
if(i == 0 || j == 0) {
dp[i][j] = 1;
continue;
}
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
return dp[m-1][n-1];
}
2、63. 不同路径 II
2.1 思路
-
dp数组以及下标的含义:机器人到达i x j网格的右下角有dp[i][j]条不同的路径 -
递推公式:
- 到达i, j-1网格,有
dp[i][j-1]条不同的路径,到达i-1, j网格,有dp[i-1][j]条不同的路径 - 所以
dp[i][j] = dp[i][j-1] + dp[i-1][j]
- 到达i, j-1网格,有
-
dp数组如何初始化:-
如果开始或结束有障碍物,返回0;
-
初始化dp[i][0];初始化dp[0][j]dp[i][0] = 1; dp[0][j] = 1- 注意代码里for循环的终止条件,一旦遇到
obstacleGrid[i][0] == 1的情况就停止dp[i][0]的赋值1的操作,dp[0][j]同理
-
-
dp数组遍历顺序:dp[i]是依赖dp[i][j-1] 和 dp[i-1][j],所以是从上到下,从左到右 -
打印
dp数组
2.2 代码
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length;
int n = obstacleGrid[0].length;
int[][] dp = new int[m][n];
// 如果开始或结束有障碍物,返回0
if(obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1) {
return 0;
}
// 初始化dp[i][0]
for(int i=0; i<m; i++) {
if(obstacleGrid[i][0] == 1) {
break;
}
dp[i][0] = 1;
}
// 初始化dp[0][j]
for(int j=0; j<n;j++) {
if(obstacleGrid[0][j] == 1) {
break;
}
dp[0][j] = 1;
}
for(int i=1; i<m; i++) {
for(int j=1; j<n; j++) {
if(obstacleGrid[i][j] == 1) {
dp[i][j] = 0;
continue;
}
dp[i][j] = dp[i][j-1] + dp[i-1][j];
}
}
return dp[m-1][n-1];
}