給定乙個矩陣m, 從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和。這是經典的動態規劃題。矩陣m的大小為n行m列。
假設m如下:13
5981
3450
6188
40首先生成乙個大小和m一樣的矩陣dp,dp中的每個元素用於記錄從(0,0)位置到達該位置的最小路徑和。對於dp[i][j],能到達該位置的只有dp[i][j-1]和dp[i-1][j],即該位置的左邊或者上面,所以dp[i][j]的值為dp[i][j-1]和dp[i-1][j]中最小的那個值加上m[i][j],再細分一下,dp[i][j]可分三種情況:
1. 第一行,i=0,此時dp[0][j]不存在上一行,所以dp[0][j]直接為前面一列的dp[0][j-1]加上m[0][j];14
9182. 第一列,j=0,此時dp[i][0]不存在左邊的列,所以dp[i][0]直接為上面一行的dp[i-1][0]加上m[i][0];19
1422
3. 除了第乙個和第一列之外,直接用dp[i][j-1]和dp[i-1][j]中最小的那個值加上m[i][j]即可。14
91895
812145
1112
2213
1512
下面用python實現上面的過程,為了方便檢視dp加入了列印。
def min_path_sum(m):
if m == none or len(m) == 0 or m[0] == none or len(m[0]) == 0:
return 0
row = len(m)
col = len(m[0])
dp = [[0]*col for i in range(row)]
print('初始化的dp為:', dp)
dp[0][0] = m[0][0]
# 設定第一列
for i in range(0, row):
dp[i][0] = dp[i-1][0] + m[i][0]
# 設定第一行
for j in range(0, col):
dp[0][j] = dp[0][j-1] + m[0][j]
print('設定完第一行和第一列後,dp為:', dp)
# 除了第一行和第一列的其它位置
for i in range(1, row):
for j in range(1, col):
dp[i][j] = min(dp[i][j-1], dp[i-1][j]) + m[i][j]
print('最終的dp為:', dp)
return dp[row-1][col-1]
輸入m,呼叫上面的方法檢視結果:
m = [[1, 3, 5, 9], [8, 1, 3, 4], [5, 0, 6, 1], [8, 8, 4, 0]]
res = min_path_sum(m)
print('最小路徑和為:', res)
結果如下:
初始化的dp為: [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]參考:《程式設計師**面試指南》左程雲。對於本題,書中提到了可以降低空間複雜度的方法,感興趣的朋友可以去看一下。設定完第一行和第一列後,dp為: [[1, 4, 9, 18], [9, 0, 0, 0], [14, 0, 0, 0], [22, 0, 0, 0]]
最終的dp為: [[1, 4, 9, 18], [9, 5, 8, 12], [14, 5, 11, 12], [22, 13, 15, 12]]
最小路徑和為: 12
矩陣的最小路徑和
準備校招的!這些是一本書的筆記 程式設計師 面試指南 it名企演算法與資料結構題目最優解 左程雲 給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和 舉例 如果給定的m如下 135 9 813 4 506 1 8...
矩陣的最小路徑和
給定乙個矩陣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。...