问题描述
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。
例如,给定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
说明:
如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/triangle
解答
''' 动态规划。时间复杂度:O(n^2),空间复杂度O(n) 1.原问题:到达第n层的最小开销 2.dp[i]表示每个不同走法带来的开销,其中i=len(triangle) 3.边界值:dp[0] = triangle[0][0] 4.状态转移方程: dp[i] = min(能走到i的全部可能) 还有一种动态规划解法,就是申请一个和三角形一样的二维数组,dp[i][j]表示到达triangle[i][j]的最优解;可以从上往下遍历,也可以从下往上遍历。 ''' class Solution(object): def minimumTotal(self, triangle): lens = 0 for i in triangle: lens += len(i) if lens == 1: return triangle[0][0] dp = [0 for _ in range(lens)] dp[0] = triangle[0][0] p = 1 q = 1 for j in range(1,len(triangle)): k = len(triangle[j]) for n in range(0,len(triangle[j])-1): if dp[n+p] == 0: dp[n+p] = triangle[j][n] + dp[p+n-q] else: if dp[n+p] > triangle[j][n] + dp[p+n-q]: dp[n+p] = triangle[j][n] + dp[p+n-q] print(n+p, triangle[j][n], dp[p+n-q]) for n in range(1,len(triangle[j])): if dp[n+p] == 0: dp[n+p] = triangle[j][n] + dp[p+n-q-1] else: if dp[n+p] > triangle[j][n] + dp[p+n-q-1]: dp[n+p] = triangle[j][n] + dp[p+n-q-1] print(n+p, triangle[j][n], dp[p+n-q-1]) p += len(triangle[j]) q+=1 mins = dp[lens-1] for i in range(lens-1 ,lens - len(triangle[-1])-1 , -1): if mins > dp[i]: mins = dp[i] return mins