(力扣每日一题)三角形最小路径和

三角形最小路径和

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。

在这里插入图片描述
在本题中,给定的三角形的行数为 n,并且第 i行(从 0 开始编号)包含了 i+1个数。如果将每一行的左端对齐,那么会形成一个等腰直角三角形,如下所示:
在这里插入图片描述

解题思路
动态规划
1、用 f[i][j]] 表示从三角形顶部走到位置 (i, j)的最小路径和。这里的位置 (i,j) 指的是三角形中第 i 行第 j 列(均从 0 开始编号)的位置。
2、由于每一步只能移动到下一行「相邻的节点」上,因此要想走到位置 (i,j),上一步就只能在位置(i−1,j−1) 或者位置 (i - 1, j)。
我们在这两个位置中选择一个路径和较小的来进行转移。

状态转移方程为:
f[i][j]=min(f[i−1][j−1],f[i−1][j])+c[i][j]
其中 c[i][j] 表示位置 (i, j) 对应的元素值。
注意第 i行有 i+1个元素,它们对应的 j 的范围为 [0,i]。

3、考虑几种特殊情况:
(1)、当 j=0 时,f[i -1][ j -1] 没有意义,此时状态转移方程需改变。
状态转移方程为:
f[i][0]=f[i−1][0]+c[i][0]

(2)、当我们在第 i行的最左侧时,我们只能从第 i−1 行的最左侧移动过来。当我们在第 i 行的最右侧时,我们只能从第 i−1 行的最右侧移动过来。
j=i 时,f[i−1][j] 没有意义,此时状态转移方程需改变。
状态转移方程为:
f[i][i]=f[i−1][i−1]+c[i][i]

(3)、定义边界条件
状态转移方程为:
f[0][0]=c[0][0]

4、最终的答案即为 f[n−1][0] 到 f[n−1][n−1] 中的最小值,其中 n 是三角形的行数。

代码

class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
      #构建三角形
        n = len(triangle)
        f = [[0] * n for _ in range(n)]
     #定义边界
        f[0][0] = triangle[0][0]

        #遍历最左边的数,即当 j=0 时
        for i in range(1, n):
            f[i][0] = f[i - 1][0] + triangle[i][0]
        #遍历中间的数,即 j<i 时
            for j in range(1, i):
                f[i][j] = min(f[i - 1][j - 1], f[i - 1][j]) + triangle[i][j]
       #遍历最右边的数(斜线上的数),即j = i 时
            f[i][i] = f[i - 1][i - 1] + triangle[i][i]
        
        #返回最小路径值
        return min(f[n - 1])

时间复杂度:O(n^2),其中 n是三角形的行数。
空间复杂度:O(n^2),我们需要一个 n∗n 的二维数组存放所有的状态。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值