1. 程式人生 > >22.最小路徑和-Leetcode 064(python)

22.最小路徑和-Leetcode 064(python)

  • 題目描述

給定一個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。

說明:每次只能向下或者向右移動一步。

  • 示例

輸入:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
輸出: 7
解釋: 因為路徑 1→3→1→1→1 的總和最小。


  • 解決思路

說實話雖然大神們都說這是最簡單的動態規劃問題了,但是我還是沒有什麼方法,在網上找的解決方案,自己用示例走了一遍,大概知道了思路是什麼樣子,然後動手去寫。過幾天再來做一遍吧。

以下內容參照網友部落格:

(1)動態規劃的特點要求利用到上一次的結果,是一種特殊的迭代思想,

(2)動態規劃的關鍵是要得到遞推關係式。

(3)對於本題,從原點到達(i, j)的最小路徑等於 :原點到達(i-1, j)最小路徑與到達(i, j-1)最小路徑中的最小值,即 dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1]。

(4)而且本題可以不申請額外空間,直接在grid中修改引數即可,這使得空間複雜度得到了有效的利用,這類做法在實際場景中常常被用到。

自己的理解:

對於一個網格來說,也許中間的點我們無法得知他從上邊過來還是從左邊過來會更好一點,但是網格左邊界和上邊界的點都是無從選擇的,上邊界的點只能從它左邊的點走過來,左邊界的點只能從它上邊走下來,因此可以把網格最上邊一行和最左邊一行的點對應的路徑和計算出來,使用直接在網格grid中修改引數的思想,這些點存放的值就是從左邊走過來(上邊界)/上邊走下來(左邊界)的路徑和,那麼中間的那些點就只需在自己的左邊和上邊選擇最小值,加上自身的值,即為走到自己的最小路徑。

  • 程式碼
class Solution(object):
    def minPathSum(self, grid):
        """
        :type grid: List[List[int]]
        :rtype: int
        """
        y = len(grid)
        x = len(grid[0])
        
        #求左邊界各點的路徑值
        for i in range(1,y):
            grid[i][0] = grid[i-1][0] + grid[i][0]
            
        #求上邊界各點的路徑值
        for j in range(1,x):
            grid[0][j] = grid[0][j-1] + grid[0][j]
            
        #中間的點的路徑值    
        for i in range(1,y):
            for j in range(1,x):
                grid[i][j] = min(grid[i-1][j],grid[i][j-1]) + grid[i][j]
                
        return grid[y-1][x-1]