题目:
题目链接: https://leetcode-cn.com/problems/triangle/
解题思路:
动态规划
状态转移公式为:
其中i为行数,j为列数
以为是三角形,不是矩形,所以如果是从上向下的遍历,需要考虑两个特殊情况(如果是从下向上,则不需要考虑):
- 遍历到当前行的第一个元素时,上一行只能取下标相同的数字
- 遍历到当前行的最后一个元素时,上一行只能取下标 - 1的数字
在设置dp数组时,只需要设置一个三角形行数(= 最后一行元素个数)的数组,从后向前的遍历(如果是从下向上,正好则后续说明相反),就可以将空间复杂度优化到O(n),状态转移公式变更为:
在更新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]