1. 程式人生 > 實用技巧 >LeetCode 64. 最小路徑和 | Python

LeetCode 64. 最小路徑和 | Python

64. 最小路徑和


題目來源:力扣(LeetCode)https://leetcode-cn.com/problems/minimum-path-sum

題目


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

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

示例:

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

解題思路


思路:動態規劃

先審題,因為題目中說明【每次只能向下或者向右移動一步】。那麼要到達終點,只能是從終點的上方或者左方到達。

狀態定義

dp[i][j]

為左上角出發到達位置 (i, j) 的最小路徑和

狀態轉移方程

前面提到,每次移動只能是向下或者向右。對於第一行元素而言(也就是 i = 0 時),只能是從左往右進行移動;對於每一列而言(也就是 j = 0 時),只能是從上往下移動。此時狀態轉移方程為:

$$
\begin{aligned}
dp[0][j] = dp[0][j-1] + grid[0][j], \qquad (i = 0; and; j > 0) \
dp[i][0] = dp[i-1][0] + grid[i][0], \qquad (i > 0; and; j = 0)
\end{aligned}
$$

對於不在第一行第一列的元素,到達位置 (i, j)

只能是從左方向右移動到達或者上方向下移動到達,此時轉移方程為:

$$
\begin{aligned}
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j], \qquad (i > 0 ; and ; j > 0)
\end{aligned}
$$

狀態初始化

dp[0][0] 表示左上角到 (0, 0) 位置的最小路徑和,也就是等於二維網格中當前元素的值。也就是:

$dp[0][0] = grid[0][0]$

最終需要求得 dp[m-1][n-1] 的值,表示從左上方到右下方的最小路徑和。

具體的程式碼實現如下。

程式碼實現


class Solution:
    def minPathSum(self, grid: List[List[int]]) -> int:
        if not grid:
            return 0

        m = len(grid)
        n = len(grid[0])

        # 定義 dp 陣列
        dp = [[0] * (n) for _ in range(m)]

        # 初始化
        dp[0][0] = grid[0][0]
        # 對第一行和第一列進行處理
        for j in range(1, n):
            dp[0][j] = dp[0][j-1] + grid[0][j]
        
        for i in range(1, m):
            dp[i][0] = dp[i-1][0] + grid[i][0]
        
        for i in range(1, m):
            for j in range(1, n):
                dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
        
        return dp[-1][-1]

實現結果


歡迎關注


公眾號 【書所集錄