动态规划(四)【三角形最小路径和】

119 阅读1分钟

三角形最小路径和

题目描述

image-20220727162905610

解题思路

如果用dp[i][j]表示第i行第j列的最小路径和,那么可以得到动态转移方程dp[i][j]=min(dp[i1][j1],dp[i1][j])+triangle[i][j]dp[i][j]=min(dp[i-1][j-1], dp[i-1][j])+triangle[i][j]

代码实现

import functools
class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        
        @functools.lru_cache()
        def dp(x,y):
            if x == 0 and y == 0:
                return triangle[x][y]
            if y == 0:
                return triangle[x][y] + dp(x-1, y)
            if y == x:
                return triangle[x][y] + dp(x-1, y-1)
            return triangle[x][y] + min(dp(x-1, y), dp(x-1, y-1))
        n = len(triangle)
        return min([dp(n-1, i) for i in range(n)])

优化方案:将二维dp数组转化为一维,要注意每一行从后往前遍历。

优化代码实现

class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        # dp[i][j]表示到坐标[i,j]的点的最小路径
        n = len(triangle)
        dp = [None] * n
        dp[0] = triangle[0][0]
        for i in range(1, n):
            j = i
            while j >= 0:
                if j == i:  # 最后一列
                    dp[j] = triangle[i][j] + dp[j-1]
                elif j == 0:
                    dp[j] = triangle[i][j] + dp[j]
                else:
                    dp[j] = triangle[i][j] + min(dp[j-1], dp[j])
                j -= 1
        return min(dp)

提交结果:

image-20210322230953811