1. 程式人生 > >【LeetCode】931. Minimum Falling Path Sum 解題報告(Python)

【LeetCode】931. Minimum Falling Path Sum 解題報告(Python)

目錄

題目描述

Given a square array of integers A, we want the minimum sum of a falling path through A.

A falling path starts at any element in the first row, and chooses one element from each row. The next row’s choice must be in a column that is different from the previous row’s column by at most one.

Example 1:

Input: [[1,2,3],[4,5,6],[7,8,9]]
Output: 12
Explanation: 
The possible falling paths are:
  • [1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9]
  • [2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9]
  • [3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9]

The falling path with the smallest sum is [1,4,7]

, so the answer is 12.

Note:

  1. 1 <= A.length == A[0].length <= 100
  2. -100 <= A[i][j] <= 100

題目大意

從最上面一行開始向下走,每次移動的時候最多隻可以移動一列。也就是說每次必須向下走一行,列可以不變、也可以向左右移動一列。求到達最後一行的時候,最短的路徑長度。

解題方法

動態規劃

剛做過類似的題目,但是我還是沒有做出來。。這個題和799香檳塔很像,都是二維空間求最大、最小的路徑問題。

此處輸入圖片的描述

如果看上面這個圖就明白了,陣列中每個位置都要從上一層獲得三個相鄰列的最小值,換句話說,每個位置都可以給下面三個相鄰列傳遞最小值。那麼,其實就是一個動態規劃嘛,到每個位置的最短路徑,就是當前數值加上到達上面那層的三個相鄰列的最小值。

所以這個題程式碼其實很簡單,只需要設定好邊界,然後我們每次查詢上面的三個最小值加上當前的位置,得到的就是到達當前位置的最小路徑。

做DP的時候,不要怕設定邊界條件。我以前總想著用各種方法想著讓dp陣列和原來的陣列一樣大,這個思想是錯誤的!因為我們記憶化搜尋的時候實際上有很多邊界條件的,其實是可以轉化成dp的邊界條件,或者說是初始條件。提前給dp陣列設定各種邊界條件,能簡化很多狀態轉移程式碼~這個題就很好的說明了這點!

時間複雜度是O(MN),空間複雜度是O(MN)。

class Solution(object):
    def minFallingPathSum(self, A):
        """
        :type A: List[List[int]]
        :rtype: int
        """
        M, N = len(A), len(A[0])
        dp = [[0] * (N + 2) for _ in range(M)]
        for i in range(M):
            dp[i][0] = dp[i][-1] = float('inf')
            for j in range(1, N + 1):
                dp[i][j] = A[i][j - 1]
        for i in range(1, M):
            for j in range(1, N + 1):
                dp[i][j] = A[i][j - 1] + min(dp[i - 1][j - 1], dp[i - 1][j], dp[i - 1][j + 1])
        return min(dp[-1])

相似題目

參考資料

日期

2018 年 10 月 28 日 —— 啊,悲傷的周賽