題目:
題目鏈接: 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]