目录
今天开始逐渐有 dp的感觉了,题目不多,就两个 不同路径,可以好好研究一下
62.不同路径
本题大家掌握动态规划的方法就可以。 数论方法 有点非主流,很难想到。
视频讲解:动态规划中如何初始化很重要!| LeetCode:62.不同路径_哔哩哔哩_bilibili
题解思路:
看完卡哥视频题解还是思路蛮清晰的,还是只依赖于上一步的结果去判断下一步的结果,这里一定需要理解清楚dp[i][j]的含义:从(0,0)走到(i,j)总共有多少种不同的路径,才好明白为什么初始化dp[0][n] = 1, dp[m][0] = 1,因为这里dp数组的含义是路径的方法,不是步数,不是步数,不是步数!!!当确定好只能向右方向走的时候,不管走到[0][n]那个格子,只有一种路径方法;当确定好只能向下方向走的时候,不管走到[m][0]那个格子,也只有一种路径方法。所以按照这种思路去考虑dp数组初始化的值!!!
class Solution {
public int uniquePaths(int m, int n) {
//动规第一步:确定dp[i][j]含义:从(0,0)走到(i,j)总共有多少种不同的路径
//动规第二步:确定递推公式dp[i][j] = dp[i-1][j](从上往下走,计算从(0,0)到(i-1, j)不同的路径的总和) + dp[i][j-1](从左往右走,计算从(0,0)到(i,j-1)不同的路径总和),因为题目规定只能向下或者向右走
//动规第三步:数组初始化,因为dp[0][n] = 1, dp[m][0] = 1
//动规第四步:确定遍历顺序,因为当前状态由上一个状态确定的,因此需要从前往后遍历
//动规第五步:打印dp数组,检查逻辑正确与否
int[][] dp = new int[m][n];
//初始化数组
for(int i = 0; i < m; i++){
dp[i][0] = 1;
}
for(int i = 0; i < n; i++){
dp[0][i] = 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. 不同路径 II
视频讲解:https://www.bilibili.com/video/BV1Ld4y1k7c6
题解思路:
本题思路和62.不同路径一样,只不过多了一个障碍物的判断,只不过需要根据给定障碍物网格进行dp数组的初始化,以及结果的计算方式!!!具体的判断条件见代码注释!!!
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m = obstacleGrid.length; //获取网格的行数
int n = obstacleGrid[0].length; //获取网格的列数
int[][] dp = new int[m][n];
//初始化dp数组
for(int i = 0; i < m; i++){
if(obstacleGrid[i][0] == 1){
break; //一旦遇到障碍物网格第0列的i行值是0时,后面就没必要再初始化了,因为不可能到达的
}
dp[i][0] = 1;
}
for(int i = 0; i < n; i++){
if(obstacleGrid[0][i] == 1){
break; //一旦遇到障碍物网格第0行第i列值是0时,后面就没必要再初始化了,因为不可能到达的
}
dp[0][i] = 1;
}
for(int i = 1; i < m; i++){
for(int j = 1; j < n; j++){
if(obstacleGrid[i][j-1] != 1 && obstacleGrid[i - 1][j] == 1){
dp[i][j] = dp[i][j-1]; //当前的位置的上方有障碍,但是当前位置的左边没障碍的时候,只能走左边那条道
}else if(obstacleGrid[i][j-1] == 1 && obstacleGrid[i - 1][j] != 1){
dp[i][j] = dp[i-1][j]; //当前的位置的上方没有障碍,当前位置的左边有障碍的时候,只能走上方那条道
}else if(obstacleGrid[i][j-1] != 1 && obstacleGrid[i - 1][j] != 1 && obstacleGrid[i][j] != 1){
dp[i][j] = dp[i][j-1] + dp[i-1][j]; //当前的位置的上方没有障碍,当前位置的左边也没有障碍的时候,可以选择走上方和走左边两条道,
//这里还有一个特殊的判断,以[[0,0][0,1]]特例说明,此时第0行和第0列所在的格子都可以初始化值为1,但是(1,1)这个位置本来就有障碍物了,因此返回值就是0,那么在判断条件上需要加上终点位置不为1的判断条件,此时返回的结果才是正确的!!!
}
}
}
return dp[m -1][n - 1];
}
}