代码随想录刷题学习日记
仅为个人记录复盘学习历程,解题思路来自代码随想录
代码随想录刷题笔记总结网址:
代码随想录
746. 使用最小花费爬楼梯
数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。
关键思路:
动规五部曲:
1.确定动规数组和下标含义
dp[i]表示到达第i台阶花费的最少体力。
2.确定递推关系
dp[i]=dp[i-1]+cost[i-1];
dp[i]=dp[i-2]+cost[i-2];
所以递推关系为:dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]).
3.dp数组如何初始化
根据题意:
dp[0]=0;
dp[1]=0;
4.确认遍历顺序
dp[i]依赖dp[i-1]/dp[i-2]从前向后遍历cost数组即可。
5.举例推导
略。
代码大致如下:
public int minCostClimbingStairs(int[] cost) {
int[] res=new int[cost.length+1];
res[0]=0;
res[1]=0;
for(int i=2;i<=cost.length;i++){
res[i]=Math.min(res[i-1]+cost[i-1],res[i-2]+cost[i-2]);
}
return res[cost.length];
}
62.不同路径
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。计算总共有多少条不同的路径?
关键思路:
1.确定动规数组和下标含义
dp[i][j] 表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。
2.确定递推关系
根据题意机器人只能向下或向右走:dp[i][j] =dp[i-1]dp[j]+dp[i][j-1].
3.dp数组如何初始化
机器人一直向下走,dp[i][0]一定都是1,只能竖着走;dp[0][j]也一样,只能横着走.
初始化为:
for(int i=0;i<m;i++)dp[i][0]=1;
for(int j=0;j<n;j++)dp[0][j]=1.
4.确定遍历顺序
dp[i][j]依赖于dp[i-1][j]和dp[i][j-1],所以从左到右,从上往下遍历。
5.举例推导
略。
代码大致如下:
public int uniquePaths(int m, int n) {
int[][]dp=new int[m][n];
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-1;i++){
for(int j=1;j<=n-1;j++){
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
63. 不同路径 II
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。考虑网格中有障碍物。计算从左上角到右下角将会有多少条不同的路径?网格中的障碍物和空位置分别用 1 和 0 来表示。
1.确定动规数组和下标含义
dp[i][j] 表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。
2.确定递推关系
当目前位置没有障碍物时进行推导,
if(dp[i][j]==0)dp[i][j] =dp[i-1]dp[j]+dp[i][j-1],
这样当障碍物的下一格计算时,比如障碍物的右边进行计算,则dp[i][j-1]=0,满足要求。
3.dp数组如何初始化
for(int i=0;i<m;i++)dp[i][0]=1;
for(int j=0;j<n;j++)dp[0][j]=1.
再遍历整个障碍物数组,遇到一的位置将dp数组对应位置置0.
4.确定遍历顺序
从左往右,从上往下遍历。
5.举例推导
略。
代码大致如下:
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m=obstacleGrid.length;
int n=obstacleGrid[0].length;
if(obstacleGrid[0][0]==1||obstacleGrid[m-1][n-1]==1)return 0;
int[][] dp=new int[m][n];
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=0;i<m;i++){
for(int j=0;j<n;j++){
if(obstacleGrid[i][j]==1)dp[i][j]=0;
}
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(obstacleGrid[i][j]==0)dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}