LeetCode:矩陣的最小路徑和
阿新 • • 發佈:2021-10-14
矩陣的最小路徑和
問題描述
給定一個 n * m 的矩陣 a,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,輸出所有的路徑中最小的路徑和。
示例:
輸入:[[1,3,5,9],[8,1,3,4],[5,0,6,1],[8,8,4,0]]
輸出:12
分析問題
因為題目要求每次只能向右或者向下走,所以對於右下角的位置,只能通過兩種方式到達,即
- 右下角的上方位置向下走。
- 右下角的左邊位置向右走。
所以,對於最後一個狀態來說,它只依賴於它上邊的狀態和它左邊的狀態,而與其它狀態無關。因此,我們可以使用動態規劃來求解,其狀態轉移方程是 dp[i] [j] = min(dp[i-1] [j] ,dp[i] [j-1])+matrix[i] [j]
下面我們來看一下臨界條件,對於第一行的元素來說,它不能從它上邊的狀態轉移過來,只能從左邊的狀態轉移過來,所以第一行的狀態轉移方程為 dp[0] [j] = d[0] [j-1] + matrix[0] [j]。同理可知,對於第一列的元素來說,它不能從它左邊的狀態轉移過來,只能從它的上邊轉移過來,所以第一列元素的狀態轉移方程為 dp[i] [0] = dp[i-1] [0] + matrix[i] [0]。
class Solution: def minPathSum(self , matrix ): # write code here m=len(matrix) if m==0: return 0 n=len(matrix[0]) #定義狀態轉移矩陣 dp=[[0]*n for _ in range(m)] #第一個元素是matrix[0][0] dp[0][0]=matrix[0][0] #處理第一列元素 for i in range(1,m): dp[i][0]=dp[i-1][0] + matrix[i][0] #處理第一行元素 for j in range(1,n): dp[0][j]=dp[0][j-1] + matrix[0][j] for i in range(1,m): for j in range(1,n): dp[i][j]=min(dp[i-1][j],dp[i][j-1])+matrix[i][j] #最後一個元素就是最小路徑和 return dp[m-1][n-1]
該演算法的時間複雜度和空間複雜度都是O(m*n),其中m代表矩陣的行數,n代表矩陣的列數。
其實,我們也不需要重新申請一個空間dp,我們可以直接複用matrix即可。
class Solution: def minPathSum(self , matrix ): # write code here m=len(matrix) if m==0: return 0 n=len(matrix[0]) #處理第一列元素 for i in range(1,m): matrix[i][0]=matrix[i-1][0] + matrix[i][0] #處理第一行元素 for j in range(1,n): matrix[0][j]=matrix[0][j-1] + matrix[0][j] for i in range(1,m): for j in range(1,n): matrix[i][j]=min(matrix[i-1][j],matrix[i][j-1])+matrix[i][j] #最後一個元素就是最小路徑和 return matrix[m-1][n-1]
最後
送大家幾本比較不錯的演算法書籍~
小爭哥資料結構與演算法
連結:https://pan.baidu.com/s/19Jk_G_-QTnGb3GRyzbENgA
密碼:keis
谷歌大佬LeetCode刷題指南
連結:https://pan.baidu.com/s/1vtRIsVltTxmIioqqkeSS5g
密碼:r3xg
演算法小抄
連結:https://pan.baidu.com/s/1rU_T6GRZ-WmV9QFmnJfCBg
密碼:unh5
更多有趣內容,請掃碼關注一波~