【leetcode系列】【算法-DP】【中等】三角形最小路径和

题目:

题目链接: https://leetcode-cn.com/problems/triangle/

 

解题思路:

动态规划

状态转移公式为:

dp[i][j] = nums[i][j] + min(dp[i - 1][j - 1], dp[i - 1][j])

其中i为行数,j为列数

以为是三角形,不是矩形,所以如果是从上向下的遍历,需要考虑两个特殊情况(如果是从下向上,则不需要考虑):

  1. 遍历到当前行的第一个元素时,上一行只能取下标相同的数字
  2. 遍历到当前行的最后一个元素时,上一行只能取下标 - 1的数字

在设置dp数组时,只需要设置一个三角形行数(= 最后一行元素个数)的数组,从后向前的遍历(如果是从下向上,正好则后续说明相反),就可以将空间复杂度优化到O(n),状态转移公式变更为:

dp[j] = nums[i][j] + min(dp[j - 1], dp[j])

在更新dp[j - 1]之前,dp[j - 1]和dp[j]保存的,实际上是上一行对应位置的值

从后向前遍历的原因,是因为更新dp[j]的时候,需要用到dp[j - 1]的值

如果从前向后遍历,会导致dp[j - 1]的值更新过早,结果不正确

代码实现:

1. 从上向下

class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        dp = [0] * (len(triangle[-1]))
        for i in range(len(triangle)):
            for j in range(len(triangle[i]) - 1, -1, -1):
                if j == 0:
                    dp[j] = triangle[i][j] + dp[j]
                elif j == len(triangle[i]) - 1:
                    dp[j] = triangle[i][j] + dp[j - 1]
                else:
                    dp[j] = triangle[i][j] + min(dp[j], dp[j - 1])

        return min(dp)

2. 从下向上

class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        dp = [0] * (len(triangle[-1]) + 1)
        for i in range(len(triangle) - 1, -1, -1):
            for j in range(len(triangle[i])):
                dp[j] = triangle[i][j] + min(dp[j], dp[j + 1])

        return dp[0]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值