【动态规划】-最小路径和(java)

265 篇文章 2 订阅
235 篇文章 0 订阅

最小路径和

题目描述

给定一个二维数组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. 预测赢家

背包问题–填满背包的最大价格

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值