【leetcode系列】【算法-DP】【中等】三角形最小路徑和

題目:

題目鏈接: https://leetcode-cn.com/problems/triangle/

 

解題思路:

動態規劃

狀態轉移公式爲:

dp[i][j] = nums[i][j] + min(dp[i - 1][j - 1], dp[i - 1][j])

其中i爲行數,j爲列數

以爲是三角形,不是矩形,所以如果是從上向下的遍歷,需要考慮兩個特殊情況(如果是從下向上,則不需要考慮):

  1. 遍歷到當前行的第一個元素時,上一行只能取下標相同的數字
  2. 遍歷到當前行的最後一個元素時,上一行只能取下標 - 1的數字

在設置dp數組時,只需要設置一個三角形行數(= 最後一行元素個數)的數組,從後向前的遍歷(如果是從下向上,正好則後續說明相反),就可以將空間複雜度優化到O(n),狀態轉移公式變更爲:

dp[j] = nums[i][j] + min(dp[j - 1], dp[j])

在更新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]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章