給定乙個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。
說明:每次只能向下或者向右移動一步。
示例:
輸入:動態規劃求解這題求的是從左上角到右下角,路徑上的數字和最小,並且每次只能向下或向右移動。所以上面很容易想到動態規劃求解。我們可以使用乙個二維陣列dp,dp[i][j]表示的是從左上角到座標(i,j)的最小路徑和。那麼走到座標(i,j)的位置只有這兩種可能,要麼從上面(i-1,j)走下來,要麼從左邊(i,j-1)走過來,我們要選擇路徑和最小的再加上當前座標的值就是到座標(i,j)的最小路徑。[1,3,1],
[1,5,1],
[4,2,1]
輸出: 7
解釋: 因為路徑 1→3→1→1→1 的總和最小。
所以遞推公式就是
dp[i][j]=min(dp[i-1][j]+dp[i][j-1])+grid[i][j];
有了遞推公式再來看一下邊界條件,當在第一行的時候,因為不能從上面走下來,所以當前值就是前面的累加。同理第一列也一樣,因為他不能從左邊走過來,所以當前值只能是上面的累加。
比如上面圖中,如果我們走到中間這一步的話,我們可以從上面1→3→5走過來,也可以從左邊1→1→5,我們取最小的即可。我們來看下**
public
intminpathsum
(int
grid)
//第一行只能從左邊走過來
for(
int i =
1; i < n; i++
)for
(int i =
1; i < m; i++)}
return dp[m -1]
[n -1]
;}
我們看到二維陣列dp和二維陣列grid的長和寬都是一樣的,沒必要再申請乙個dp陣列,完全可以使用grid,來看下**
public
intminpathsum
(int
grid)
else
if(j ==0)
else}}
return grid[m -1]
[n -1]
;}
遞迴求解我們還可以把上面的動態規劃改為遞迴,定義乙個函式
minpathsum(int grid, int i, int j)表示從左上角到座標(i,j)的最短路徑和,那麼同樣道理,要走到座標(i,j)只能從上面下來或者左邊過來。所以**輪廓我們大致能寫出來
public
intminpathsum
(int
grid,
int i,
int j)
//一些邏輯處理
//取從上面走下來和從左邊走過來的最小值+當前座標的值
return grid[i]
[j]+ math.
min(
minpathsum
(grid, i -
1, j)
,minpathsum
(grid, i, j -1));}
下面再來看下完整**
public
intminpathsum
(int
grid)
public
intminpathsum
(int
grid,
int i,
int j)
因為這裡面的遞迴會導致大量的重複計算,所以還是老方法,就是把計算過的值儲存到乙個map中,下次計算的時候先看map中是否有,如果有就直接從map中取,如果沒有再計算,計算之後再把結果放到map中,來看下**
public
intminpathsum
(int
grid)
public
intminpathsum
(int
grid,
int i,
int j, map
map)
總結這題使用動態規劃應該說是最容易理解的,也可以參照前面的409,動態規劃求不同路徑和411,動態規劃和遞迴求不同路徑 ii,只不過遞推公式會有點差別。
動態規劃 最小路徑和
給定乙個只含非負整數的m n網格,找到一條從左上角到右下角的可以使數字和最小的路徑。你在同一時間只能向下或者向右移動一步 樣例1 1 3 1 1 5 1 4 2 1 輸出 7 樣例2 1 3 5 9 8 1 3 4 5 0 6 1 8 8 4 0 輸出 12 計算到達當前位置路徑,是在上一步的基礎上...
最小路徑和 動態規劃
給定乙個包含非負整數的m n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總合為最小.說明 每次只能向下或者向右移動一下.示例 輸入 1,3,1 1,5,1 4,2,1 輸出 7解釋 因為路徑 1 3 1 1 1 的總和最小。解法一 動態規劃思想因為最近在做動態規劃的專題,所以用動態規劃...
遞迴和動態規劃 矩陣的最小路徑和
給你乙個二維陣列,二維陣列中的每個數都是正數,要求從左上角走到右下角,每一步只能向右或者向下。沿途經過的數字要累加起來。返回最小的路徑和。解 暴力遞迴 因為是從左上角到右下角,只能向右或者向下,可以使用遞迴,把問題簡化為 當前位置 i,j 和右邊位置 i 1,j 和下面位置 i,j 1 之間的問題 ...