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

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

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

题目: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 为三角形的总行数)来解决这个问题,那么你的算法会很加分。

前言

换个角度看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列元素的最小路径和
dp最后一行 = triangle最后一行
常规:
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]

代码实现

from typing import List
class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        n = len ( triangle )  # 三角形行数 n=4
        dp = [[0] * (n + 1) for _ in range ( n + 1 )]  # 生成一个(n+1)*(n+1)的零矩阵,用来存放当前路径长度

        for i in range ( len ( triangle ) - 1, -1, -1 ):  # 遍历三角形每一行
            for j in range ( 0, i + 1, 1 ):  # 遍历三角形每一列
                dp[i][j] = min ( dp[i + 1][j], dp[i + 1][j + 1] ) + triangle[i][j]

        return dp[0][0]

print ( Solution ().minimumTotal ( [
    [2],
    [3, 4],
    [6, 5, 7],
    [4, 1, 8, 3]
] ) )

时间复杂度:O(n^2) (n 为三角形的总行数)
空间复杂度:O(n^2) (n 为三角形的总行数)
在这里插入图片描述
空间优化一:将存放结果的数据结构由矩阵变为一维数组

from typing import List
class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        n = len ( triangle ) # 三角形行数
        dp = [0] * (n + 1) # 生成一个n+1的零列表

        for i in range ( len ( triangle ) - 1, -1, -1 ):
            for j in range ( 0, i + 1, 1 ):
                dp[j] = min ( dp[j], dp[j + 1] ) + triangle[i][j]

        return dp[0]


print ( Solution ().minimumTotal ( [
    [2],
    [3, 4],
    [6, 5, 7],
    [4, 1, 8, 3]
] ) )

时间复杂度:O(n^2) (n 为三角形的总行数)
空间复杂度:O(n) (n 为三角形的总行数)
在这里插入图片描述
空间优化二:不新创建一个放置结果的矩阵,直接使用参数三角形的矩阵,求得的结果直接覆盖原位置。

class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        for i in range ( len ( triangle ) - 2, -1, -1 ):  # 遍历三角形每一行
            for j in range ( 0, i + 1, 1 ):  # 遍历三角形每一列
                triangle[i][j] = min ( triangle[i + 1][j], triangle[i + 1][j + 1] ) + triangle[i][j]
        return triangle[0][0]

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

方法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/107350782