最小路劲和--动态规划和内存压缩
- 最小路径和
- 题目描述
- 动态规划解题思路:
- 代码演示
- 动态规划的内存压缩
- 动态规划专题
最小路径和
题目描述
给定一个二维数组matrix,一个人必须从左上角出发,最后到达右下角 沿途只可以向下或者向右走,沿途的数字都累加就是距离累加和 返回最小距离累加和
示例:
动态规划解题思路:
以上图(0,1)位置为例,他的最小路径只能是(0,0) + (0,1),因为他只有左边位置,没有上面位置。
但(1,1)位置要选最小路径,就要比较,从(0,1)位置走到(1,1)位置和(1,0)位置走到(1,1)位置哪个距离最小了。
根据上面思路,我们先可以把第0行和第0列的值在动态规划表中初始化出来。
然后其他一般位置,不断比较这个位置的左边和上边两个位置哪个距离小,取哪个。
好了,开始代码演示
代码演示
/**
* 最小路径和
* @param m
* @return
*/
public static int minPathSum1(int[][] m) {
//行的长度
int rowSize = m.length;
//列的长度
int colSize = m[0].length;
//初始化动态规划表
int[][]dp = new int[rowSize][colSize];
//先初始化(0,0)位置
dp[0][0] = m[0][0];
//再初始化第0行所有列的数据
for (int i = 1;i < colSize;i++){
dp[0][i] = dp[0][i - 1] + m[0][i];
}
//初始化第一列所有行的数据。
for (int j = 1;j < rowSize;j++){
dp[j][0] = dp[j - 1][0] + m[j][0];
}
//初始化一般位置
for (int i = 1;i < rowSize;i++){
for (int j = 1;j < colSize;j++){
//比较左边位置和上面位置,取最小值,然后加上当前点本身的值,就是路径最小的值
dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1]) + m[i][j];
}
}
//返回走到最后的最小路径
return dp[rowSize - 1][colSize - 1];
}
动态规划的内存压缩
动态规划表是个二维表,但其实我们只要其中一个数据,所以就可以想办法去压缩下内存。
我们只要其中一行的数据的话,就会变成一个一维数组。这个数组值不断向下面一行更新,最终到最后一行,我们取出右下角的值就可以了。
代码演示
/**
* 最小路径和 内存压缩。
* @param m
* @return
*/
public static int minPathSum2(int[][] m) {
//行的长度
int rowSize = m.length;
//列的长度
int colSize = m[0].length;
//每次只保存一行的数据
int[]nums = new int[colSize];
//初始化初始位置
nums[0] = m[0][0];
//先把第一行初始化出来,因为没有上面位置,只依赖左边,所以相加就行。
for (int i = 1;i < colSize;i++){
nums[i] = nums[i - 1] + m[0][i];
}
//不断滚动向下更新 第二行---一直到最后一行
for (int i = 1;i < rowSize;i++){
//每行的第一个位置,因为没有左边数据,只依赖上面的数据,所以可以先初始化出来
nums[0] = nums[0] + m[i][0];
for (int j = 1;j < colSize;j++){
//比较上面和左边的最小值,加上本身的值
nums[j] = Math.min(nums[j - 1],nums[j]) + m[i][j];
}
}
//返回到右下角的最小路径。
return nums[colSize - 1];
}
动态规划专题
象棋里马走到指定位置的方法数
最长回文子序列
leetcode.486. 预测赢家
背包问题–填满背包的最大价格