題目描述:給定一個 m×n 的非負整數矩陣 grid,從左上角出發,每次只能向右或向下移動,求抵達右下角的路徑中,數值總和最小的那條路徑的和。
解題思路:
這是典型的二維動態規劃問題。定義 dp[i][j] 為從左上角 (0,0) 走到 (i,j) 的最小路徑和。
轉移關係:
dp[0][j] = dp[0][j-1] + grid[0][j]dp[i][0] = dp[i-1][0] + grid[i][0]dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])為節省空間,可直接在原始 grid 上原地修改,不需額外的 dp 陣列。最終答案為 grid[m-1][n-1]。
此方法正確的原因是:到達任意格子 (i,j) 只有兩種可能的前一步(從上或從左),取兩者較小的已知最優值再加上當前格子的代價,即為到達 (i,j) 的全域最優解,無後效性成立。
時間複雜度:O(m×n) — 每個格子只被訪問並更新一次,總共需要處理 m×n 個格子。
空間複雜度:O(1) — 採用原地修改 grid 的方式,不需要額外的 dp 陣列;若不允許修改輸入,則需 O(n) 的滾動陣列或 O(m×n) 的獨立 dp 表。
1. Let m = rows, n = cols of grid
2. For j from 1 to n-1: grid[0][j] += grid[0][j-1] // first row prefix sums
3. For i from 1 to m-1: grid[i][0] += grid[i-1][0] // first col prefix sums
4. For i from 1 to m-1:
For j from 1 to n-1:
grid[i][j] += min(grid[i-1][j], grid[i][j-1])
5. Return grid[m-1][n-1]方法一:遞迴 + 記憶化(Top-Down DP)
從右下角往左上角遞迴,memo[i][j] 記錄 (i,j) 到終點的最小和,避免重複計算。時間複雜度 O(m×n),空間複雜度 O(m×n)(記憶化表 + 遞迴堆疊)。邏輯直觀,但常數較大。
方法二:滾動陣列優化(Rolling Array)
觀察到 dp[i][j] 只依賴 dp[i-1][j] 和 dp[i][j-1],可用一維 dp 陣列 dp[n] 做滾動更新:遍歷每一行時,dp[j] = grid[i][j] + min(dp[j], dp[j-1]),其中 dp[j] 代表上一行同列的值,dp[j-1] 代表同行前一列的值。時間複雜度 O(m×n),空間複雜度降至 O(n),適合在不能修改輸入的情況下節省記憶體。