算法52-----矩陣最小路徑【動態規劃】
阿新 • • 發佈:2018-11-17
sum data 列表 路徑 二次 解釋 示例 一行 lse
一、題目:矩陣最小路徑
給定一個包含非負整數的 m x n 網格,請找出一條從左上角到右下角的路徑,使得路徑上的數字總和為最小。
說明:每次只能向下或者向右移動一步。
示例:
輸入: [ [1,3,1], [1,5,1], [4,2,1] ] 輸出: 7 解釋: 因為路徑 1→3→1→1→1 的總和最小。
思路1:時間O(M*N),空間O(M*N)
新建一個矩陣dp(大小也是M*N),該矩陣是從上往下,從左往右記錄每一步的結果的,當前的結果可以根據該矩陣上面和左邊最小的值來獲得,即:
dp[i][j] = min(dp[i][j-1],dp[i-1][j]) + grid[i][j]
如:
grid = [ [1,3,1], |
dp = [[1,4,5], |
所以結果為dp[-1][-1] = 7
代碼:
def minPathSum(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
# 使用二維數組
if not grid or not grid[0]:
return 0
matrix = list(zip(*grid))
if len(grid) <= 1:
return sum(grid[0])
if len(matrix) <= 1:
return sum(matrix[0])
dp = [[0]*len(grid[0]) for i in range(len(grid))]
dp[0][0] = grid[0][0]
for i in range(1,len(grid)):
dp[i][0] = grid[i][0] + dp[i-1][0]
for j in range(1,len(grid[0])):
dp[0][j] = grid[0][j] + dp[0][j-1]
for i in range(1,len(grid)):
for j in range(1,len(grid[0])):
dp[i][j] = min(dp[i][j-1],dp[i-1][j]) + grid[i][j]
return dp[-1][-1]
思路2:時間O(M*N),空間O( min(M,N) )
新建一個列表dp(大小為min(M,N)),循環行數次更新記錄每一行的路徑值。
如:
grid =
[ [1,3,1],
[1,5,1],
[4,2,1]]
第一次更新:dp = [1,4,5]
第二次更新:dp = [2,7,6],比如:原本dp = [1,4,5],然後 先將 dp[0] 更新為2,然後dp[1] : 【min ( dp[0] 和dp [1] ) 與grid [1][1]相加之和】來更新 dp [1]
第三次更新:dp = [6,8,7]
更新是根據:
dp[j] = min(dp[j-1],dp[j]) + grid[i][j]
代碼:
#使用一維數組
if not grid or not grid[0]:
return 0
if len(grid) <= 1:
return sum(grid[0])
if len(grid[0]) <= 1:
return sum([val[0] for val in grid])
n = min(len(grid),len(grid[0]))
m = len(grid) if n == len(grid[0]) else len(grid[0])
dp = [0] * n
dp[0] = grid[0][0]
if n == len(grid):
grid = list(zip(*grid))
for i in range(1,n):
dp[i] = grid[0][i] + dp[i-1]
for i in range(1,m):
for j in range(n):
dp[j] = min(dp[j-1],dp[j]) + grid[i][j] if j>=1 else dp[j] + grid[i][j]
return dp[-1]
算法52-----矩陣最小路徑【動態規劃】