【JAVA】三角形最小路径和——力扣每日一题(二)(2020.07.14)

如果你从本文中学习到丝毫知识,那么请您点点关注、点赞、评论和收藏
大家好,我是爱做梦的鱼,我是东北大学大数据实验班大三的小菜鸡,非常渴望优秀,羡慕优秀的人,个人博客为:爱做梦的鱼https://zihao.blog.csdn.net/,微信公众号、微信视频号为【程序猿干货铺】,qq交流群为:1107710098
程序猿干货铺

如果你同样热爱算法,那么请关注我,我将每日更新力扣的每日一题的题解+代码,每周更新力扣周赛题解+代码
《本题Python3代码版》
专栏《力扣每日一题》
专栏《力扣周赛》
专栏《力扣大厂模拟面试算法题》

题目:120. 三角形最小路径和

题目地址(点击直接跳转)https://leetcode-cn.com/problems/triangle/

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

相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。

例如,给定三角形:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

说明:

如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。

扫描二维码关注公众号,回复: 11435942 查看本文章

前言

换个角度看triangle

     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
  [2],
  [3,4],
  [6,5,7],
  [4,1,8,3]

方法一:自底向上

方法1:动态规划(DP)

思路分析
状态定义:
dp[i][j]表示包含第i行第j列元素的最小路径和
常规:
triangle[i][j]一定会到达triangle[i+1][j]或者triangle[i+1][j+1],
所以状态dp[i][j]一定等于dp[i+1][j]或者dp[i+1][j+1]的最小值+triangle[i][j]
转换方程:dp[i][j]=min(dp[i+1][j],dp[i+1][j+1])+triangle[i][j]

代码实现

 public int minimumTotal(List<List<Integer>> triangle) {
        // 加1可以不用专门初始化dp最后一行
        // 根据题意,行列值相同
        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];
    }

在这里插入图片描述
时间复杂度:O(n^2) (n 为三角形的总行数)
空间复杂度:O(n^2) (n 为三角形的总行数)

空间优化,将结果数组从二维降为一维

public int minimumTotal(List<List<Integer>> triangle) {
    // dp中记录了求第i行时,第i+1的最小路径和
    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];
}

在这里插入图片描述
时间复杂度:O(n^2) (n 为三角形的总行数)
空间复杂度:O(n) (n 为三角形的总行数)

空间优化二,不新创建一个放置结果的数据结构(二维或一维),直接使用参数三角形的矩阵,求得的结果直接覆盖原位置。

public int minimumTotal(List<List<Integer>> triangle) {
        for (int i = triangle.size() - 2; i >= 0; i--) {
            for (int j = 0; j <= i; j++) {
                int temp = Math.min(triangle.get(i + 1).get(j), triangle.get(i + 1).get(j + 1)) + triangle.get(i).get(j);
                List<Integer> temp2 = triangle.get(i);
                temp2.set(j, temp);
                triangle.set(i, temp2);
            }
        }
        return triangle.get(0).get(0);
    }

在这里插入图片描述

方法2:递归(晚点补充)

方法二:自顶向下

大家去看力扣官方题解吧,力扣官方讲的真的又细又好,非常建议大家去看 作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/triangle/solution/san-jiao-xing-zui-xiao-lu-jing-he-by-leetcode-solu/
来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

猜你喜欢

转载自blog.csdn.net/weixin_43124279/article/details/107345020