2024/6/7 今天天气转晴,将栀子花移动到二楼阳台,愿它好!昨天准备做完这题再回去,太晚了感觉很疲惫,做不下去,今天早上来把它做了。
1、题目描述
2、逻辑分析
昨天上午做过一个跳格子的题目,也是运用同样的动态规划思想来解题。每次只能向下或向右移动一格,算法思想就是:每次选择较短的路来走。
- 网格的第一行的每个元素只能从左上角元素开始向右移动到达
- 网格的第一列的每个元素只能从左上角元素开始向下移动到达
- 不在第一行和第一列的元素,可以从其上方相邻元素向下移动一步到达,或者从其左方相邻元素向右移动一步到达.元素对应的最小路径和等于其上方相邻元素与其左方相邻元素两者对应的最小路径和中的最小值加上当前元素的值。
用表达式可以这样表示:
3、代码演示
public int minPathSum(int[][] grid) {
// 如果网格为空、没有行或没有列,则直接返回0
if(grid == null || grid.length == 0 || grid[0].length == 0 ){
return 0;
}
// 获取网格的行数和列数
int row = grid.length, cloum = grid[0].length;
// 创建一个与原始网格大小相同的二维数组dp,用于存储到达每个格子的最小路径和
int [][] dp = new int[row][cloum];
// 初始化dp数组的第一个元素(左上角)为原始网格的第一个元素
dp[0][0] = grid[0][0];
// 初始化第一行(只能向右移动)
for(int i = 1; i < row; i++){
dp[i][0] = dp[i - 1][0] + grid[i][0];
}
// 初始化第一列(只能向下移动)
for(int j = 1; j < cloum; j++){
dp[0][j] = dp[0][j -1] + grid[0][j];
}
// 填充dp数组的其余部分
for(int i = 1; i < row; i++){
for(int j = 1; j < cloum; j++){
// 到达当前格子的最小路径和是上方格子和左方格子的最小路径和加上当前格子的值
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
}
}
// 返回右下角格子的最小路径和,即最终答案
return dp[row -1][cloum - 1];
}
以上代码注释较为详尽,主要是要有dp思想,上题做的是不同路径,这题是最短路径,得找个时间去总结,比较,才会有质变吧,有时候发觉学习方法不太好,也不愿意做改变,不愿意破井而出。Anyway,看看对应的复杂度
4、复杂度分析
- 时间复杂度:O(mn),因为要遍历整个数组,数组大小就是mn。
- 空间复杂度:O(mn),因为要创建一个dp数组来存储路径,大小也正好是mn。
ok,做的两道dp题目都很简单,至少代码很简单哈哈,那这题就先到这里了,拜拜!