準備校招的!
這些是一本書的筆記-—程式設計師**面試指南:it名企演算法與資料結構題目最優解(左程雲)。
> **給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,
路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和**。
> 【舉例】如果給定的m如下:
> 135
9
> 813
4
> 506
1
> 884
0 路徑1,3,1,0,6,1,0是所有路徑中路徑和最小的,所以返回12。
這正式進入動態規劃的演算法了!
經典動態規劃方法。
假設矩陣m的大小為m×n,行數為m,列數為n。
先生成大小和m一樣的矩陣dp,dp[i]
[j]的值表示從左上角(即(0,0))位置走到(i ,j)位置的最小路徑和。
對m的第一行的所有位置來說,即(0,j)(0≤j
0,0)位置走到(0,j)位置只能向右走,
所以(0,0)位置到(0,j)位置的路徑和就是m[0]
[0..j]這些值的累加結果。
同理,對m的第一列的所有位置來說,即(i,0)(0≤i
0,0)位置走到(i,0)位置只能向下走,
所以(0,0)位置到(i,0)位置的路徑和就是m[0..i]
[0]這些值的累加結果。
以題目中的例子來說,dp第一行和第一列的值如下:
14918914
22 除第一行和第一列的其他位置(i ,j)外,
都有左邊位置(i-1,j)和上邊位置(i ,j-1)。從(0,0)到(i ,j)的路徑必然經過位置(i-1,j)或位置(i ,j-1),
所以,dp[i]
[j]=min+m[i]
[j],含義是比較從(0,0)位置開始,
經過(i-1,j)位置最終到達(i,j)的最小路徑和經過(i ,j-1)位置最終到達(i ,j)的最小路徑之間
,哪條路徑的路徑和更小。 那麼更小的路徑和就是dp[i]
[j]的值。
以題目的例子來說,最終生成的dp矩陣如下:
14918958
1214511
1222
1315
12 除第一行和第一列之外,每乙個位置都考慮從左邊到達自己的路徑和更小還是從上邊達到自己的路徑和更小。
最右下角的值就是整個問題的答案。具體過程請參看如下**中的f方法。
依據上面的解析一步一步敲**(自己敲出來才能很好理解):
public
static
intf(int m)
int rows=m.length;//行
int cols=m[0].length;//列
/** * dp[i][j]表示m[0][0]到m[i][j]的最短路徑
*/int dp=new
int[rows][cols];
dp[0][0]=m[0][0];
//第一行計算最短路徑,只能向右走
for(int j=1;j0][j]=dp[0][j-1]+m[0][j];
}//第一列計算最短路徑,只能向下走
for(int i=1;i0]=dp[i-1][0]+m[i][0];
}//計算dp[i][j]的值
for(int i = 1 ; i < rows ; i++)
}return dp[rows-1][cols-1];
}
測試:
public
static
void
main(string args) ,,,};
system.out.println(f(m));
}
執行:
這種動態規劃將問題一步一步分解,首先從最簡單的情況開始–單行單列,其次依次增加複雜度,一步一步求解….
來個搞笑gif
矩陣的最小路徑和
給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和。方法一 遞迴 coding utf 8 defsolution m,l n l m 0 0 if len m 1 and len m 0 1 return l ...
矩陣的最小路徑和
題目 給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後達到右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和。舉例 給定的m如下 1 3 5 9 8 1 3 4 5 0 6 1 8 8 4 0 路徑1,3,1,0,6,1,0是所有路徑中路徑和最小的,所以返回12。...
矩陣的最小路徑和
給定乙個矩陣matrix,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中的最小路徑和。如果給定的矩陣matrix如下 其中路徑1,3,1,0,6,1,0是所有路徑中路徑和最小的,所以返回12。下面我們使用遞迴的方法來處理這個問題。假設現...