LeetCode#64 最小路徑和 Java

@author: sdubrz
@date: 2020.04.17
題號: 64
題目難度: 中等
考察內容: 動態規劃
原題鏈接 https://leetcode-cn.com/problems/minimum-path-sum/
題目的著作權歸領釦網絡所有,商業轉載請聯繫官方授權,非商業轉載請註明出處。
解題代碼轉載請聯繫 lwyz521604#163.com

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

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

示例:

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

通過次數77,450 提交次數118,548

動態規劃解法

使用動態規劃的關鍵是尋找最優子結構。從起始位置出發,到第 m 行的元素必須經過第 m-1 行。因而要計算從初始位置到第 m 行中的元素的最小代價可以先計算到第 m-1 行中的元素的最小代價。

這樣,這個問題的子結構就可以基本確定下來了。我們需要計算在已知前 i 行元素的情況下,從初始位置到第 i 行中的元素的代價。對於第 i 行中的第 j 個元素,到達它有兩種途徑:

  • 從第 i 行、第 j-1 個元素到達
  • 從第 i-1 行、第 j 個元素到達

我們需要挑選這兩種途徑中代價較小的那個。

我們每次讀取矩陣的一行,計算從初始位置到當前行中元素的最小代價。由於在計算到第 i 行中元素的最小代價時,只需要查看到第 i-1 行元素的代價以及第 i 行中的元素本身,因而,在迭代的過程中,我們不需要再去更新前面的 i-2 行元素的代價。

下面是具體的代碼實現:

class Solution {
    public int minPathSum(int[][] grid) {
        int m = grid.length;
        if(m==0){
            return 0;
        }
        int n = grid[0].length;
        if(n==0){
            return 0;
        }

        for(int i=1; i<n; i++){
            grid[0][i] = grid[0][i] + grid[0][i-1];
        }

        for(int i=1; i<m; i++){
            grid[i][0] = grid[i-1][0] + grid[i][0];
            for(int j=1; j<n; j++){
                int s1 = grid[i][j] + grid[i][j-1];
                int s2 = grid[i][j] + grid[i-1][j];
                grid[i][j] = Math.min(s1, s2);
            }
        }

        return grid[m-1][n-1];
    }
}

在 LeetCode 系統中提交的結果如下所示

執行結果: 通過 顯示詳情
執行用時 : 3 ms, 在所有 Java 提交中擊敗了 89.15% 的用戶
內存消耗 : 42.6 MB, 在所有 Java 提交中擊敗了 24.24% 的用戶

圖論方法

這個問題應該也可以通過構造一個有向圖,然後用 Dijkstra 算法來求解。不過那種方法應該不會比動態規劃的方法簡單快捷。

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