leetcode每日一题 使用golang和java实现 三角形最小路径和

三角形的最小路径和

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
题目示例

解题思路

毋庸置疑,这又是一道动态规划的dp问题,跟上次的地下城救公主类似,这次要求最短路径,采取同样的思路,也是使用一个反向dp的思路。

  1. 首先将题目中给的数组变为如下形式
    [2]
    [3,4]
    [6,5,7]
    [4,1,8,3]
    这样一来,数组转化成一个只有主对角线以下元素的二维数组。
  2. 将每一个节点的数值转换为到达最低端的最小路径值,也就是把该位置的元素的值变成自己的值 + 自己下面一行正下方元素和正下方元素右边一个值中更小的那个,这时我需要用到一个状态转移方程:
    f[i][j]=min(f[i−1][j−1],f[i−1][j])+c[i][j]
  3. 这样一来,数组的0,0元素的值就是要求的第一个值到最下面一行的最小路径值。

golang实现代码

实现步骤:

  1. 定义变量 i = 数组的长度 - 2,也就是从数组的倒数第二行开始遍历,一直遍历到第一行,这也是反向dp思想的体现(因为数组的最后一行到达最后一行的最小路径就是本身的值,所以无需变化)
  2. 然后从该行的第一个元素开始向后遍历,由于是主对角线以下(包括主对角线)存在元素,所以定义变量 j = 0,循环结束条件为 j <= i 。
  3. 然后将每一个位置的元素换成状态转移方程的结构(具体参照以上解体思路)
  4. 最终返回0,0的值即为所求。
func minimumTotal(triangle [][]int) int {
    for i := len(triangle) - 2; i>= 0; i--{//从倒数第二行开始遍历
        for j := 0;j <= i; j++{//结束条件为遍历到主对角线为止
            if triangle[i+1][j] > triangle[i+1][j+1]{
                triangle[i][j] = triangle[i+1][j+1] + triangle[i][j]
            }else{
                triangle[i][j] = triangle[i+1][j] + triangle[i][j]
            } //将元素值替换为状态转移方程的纸
        }
    }
    return triangle[0][0]
}

golang测试结果如下:
golang测试结果

java实现代码

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int[][] dp = new int[triangle.size() + 1][triangle.size() + 1];
        for(int i = triangle.size() - 1; i >= 0; i--){
            for(int j = 0; j <= i; j++){
                dp[i][j] = Math.min(dp[i+1][j], dp[i+1][j+1]) + triangle.get(i).get(j);
            }
        }
        return dp[0][0];
    }
}

但是这种解决办法存在某些不足,

使用二维数组进行反向dp测试结果

因此我进行了如下改进和优化:

将原来的二维数组改成一维数组,如下图:

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int[] dp = new int[triangle.size()+1];
        for(int i = triangle.size() - 1; i >= 0; i--){
            for(int j = 0; j <= i; j++){
                dp[j] = Math.min(dp[j],dp[j+1]) + triangle.get(i).get(j);
            }
        }
        return dp[0];
    }
}

使用一维数组进行反向dp测试结果
相比之前会有一定的优化。

golang和java区别比较

使用相同的算法,golang相比之下会更优一些,首先是因为在java中使用了ArrayList集合,其中有些不足所以不可以在指定位置进行数据的修改,因此需要转化成数组的形式,在这一过程中会浪费用时和内存,但是golang的数组执行起来就可以自由替换,因此更方便一些。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值