【动态规划-矩阵】4.三角形最小路径和
题目
难度: 中等
题目内容:
给定一个三角形 triangle ,找出自顶向下的最小路径和。
每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 i 或 i + 1 。
示例1:
输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
输出:11
解释:如下面简图所示:
2
3 4
6 5 7
4 1 8 3
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
示例2:
输入:triangle = [[-10]]
输出:-10
前置思路
题设中已经给出提示,前一行某一个位置只能下移到下一行i或i+1的位置,反过来,某一行的位置只能从上一行i或i-1的位置移动过来,那么移动到该位置的最小路径为两者小值+本位置的路径值。
然后最后一行取最小值即可。
代码
class Solution:
def minimumTotal(self, triangle: List[List[int]]) -> int:
for i in range (1,len(triangle)):
for j in range(len(triangle[i])):
# 三种情况,两个边界+非边界
if j == 0:
triangle[i][j] += triangle[i-1][j]
elif j == len(triangle[i]) - 1:
triangle[i][j] += triangle[i-1][j-1]
else:
triangle[i][j] += min(triangle[i-1][j],triangle[i-1][j-1])
return min(triangle[-1])
大神解
class Solution:
def minimumTotal(self, triangle: List[List[int]]) -> int:
n = len(triangle)
dp = [[0] * (i+1) for i in range(n)]
dp[-1] = triangle[-1]
for i in range(n-2, -1, -1):
for j, x in enumerate(triangle[i]):
dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + x
return dp[0][0]
这里我一开始没想到,如果倒着走可以省去最后一步求最小值的计算。
从倒数第二层开始遍历,可以预知到每一个位置会选择的下一个位置,这样一步步往上做筛选,最终会得到唯一的最小值。
思考
这一题的优化方案提供了一个很好的思路——路径是可逆的,如果遇到类似的问题可以多一种思考的方式,代码走向尽量去往更简单的结果。