題目描述
給定一個(gè)包含非負(fù)整數(shù)的 m x n 網(wǎng)格,請找出一條從左上角到右下角的路徑,使得路徑上的數(shù)字總和為最小。
說明:每次只能向下或者向右移動(dòng)一步。
示例:
輸入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
輸出: 7
解釋: 因?yàn)槁窂?1→3→1→1→1 的總和最小。
思路解析
找到一條從左上角到右下角的路徑,路徑之和最小。
每個(gè)元素,向右走或者向下走。兩條路,找到一條路徑之和最小的一個(gè)。
cost(i, j)= grid[i][j] + min(cost(i+1, j), cost(i, j+1))
需要求的就是cost(0, 0)
申請動(dòng)態(tài)規(guī)劃數(shù)組dp[m][n],初始化右下角的值grid[m-1][n-1]??紤]bottom和right,能夠直接初始化。dp[m-1][j] = grid[i][j] + dp[i][j+1]
dp[i][n-1] = grid[i][n-1] + dp[i+1][n-1]
除此之外,就是狀態(tài)轉(zhuǎn)移dp[i][j] = grid[i][j] + min(dp[i+1][j], dp[i][j+1])
class Solution:
def minPathSum(self, grid):
if not grid:
return 0
m = len(grid)
n = len(grid[0])
dp = [[0 for _ in range(n)] for _ in range(m)]
for i in range(m-1, -1, -1):
for j in range(n-1, -1, -1):
if i == m-1 and j != n-1:
dp[i][j] = grid[i][j] + dp[i][j+1]
elif j == n-1 and i != m-1:
dp[i][j] = grid[i][j] + dp[i+1][j]
elif i != m-1 and j != n-1:
dp[i][j] = grid[i][j] + min(dp[i][j+1], dp[i+1][j])
else:
dp[i][j] = grid[i][j]
return dp[0][0]

優(yōu)化
每一個(gè)狀態(tài)依賴右側(cè)或者下側(cè)。利用最后一行,沒有向下的,動(dòng)態(tài)轉(zhuǎn)移賦值。在上個(gè)解法中,我們可以用一個(gè)一維數(shù)組來代替二維數(shù)組,dp 數(shù)組的大小和列大小相同。這是因?yàn)閷τ谀硞€(gè)固定狀態(tài),只需要考慮下方和右側(cè)的節(jié)點(diǎn)。首先初始化 dp 數(shù)組最后一個(gè)元素是右下角的元素值,然后我們向左移更新每個(gè) dp(j) 為:
dp(j)=grid(i,j)+min(dp(j),dp(j+1))
我們對于每一行都重復(fù)這個(gè)過程,然后向上一行移動(dòng),計(jì)算完成后 dp(0) 就是最后的結(jié)果。
class Solution:
# def minPathSum(self, grid):
# if not grid:
# return 0
# m = len(grid)
# n = len(grid[0])
# dp = [[0 for _ in range(n)] for _ in range(m)]
# for i in range(m-1, -1, -1):
# for j in range(n-1, -1, -1):
# if i == m-1 and j != n-1:
# dp[i][j] = grid[i][j] + dp[i][j+1]
# elif j == n-1 and i != m-1:
# dp[i][j] = grid[i][j] + dp[i+1][j]
# elif i != m-1 and j != n-1:
# dp[i][j] = grid[i][j] + min(dp[i][j+1], dp[i+1][j])
# else:
# dp[i][j] = grid[i][j]
# return dp[0][0]
def minPathSum(self, grid):
if not grid:
return 0
m = len(grid)
n = len(grid[0])
dp = [0 for _ in range(n)]
for i in range(m - 1, -1, -1):
for j in range(n - 1, -1, -1):
if i == m - 1 and j != n - 1:
dp[j] = grid[i][j] + dp[j + 1]
elif j == n - 1 and i != m - 1:
dp[j] = grid[i][j] + dp[j]
elif i != m - 1 and j != n - 1:
dp[j] = grid[i][j] + min(dp[j + 1], dp[j])
else:
dp[j] = grid[i][j]
return dp[0]

優(yōu)化
直接在數(shù)組上修改,減少空間復(fù)雜度