题目描述
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
思路解析
找到一条从左上角到右下角的路径,路径之和最小。
每个元素,向右走或者向下走。两条路,找到一条路径之和最小的一个。
cost(i, j)= grid[i][j] + min(cost(i+1, j), cost(i, j+1))
需要求的就是cost(0, 0)
申请动态规划数组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]
除此之外,就是状态转移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]
优化
每一个状态依赖右侧或者下侧。利用最后一行,没有向下的,动态转移赋值。在上个解法中,我们可以用一个一维数组来代替二维数组,dp 数组的大小和列大小相同。这是因为对于某个固定状态,只需要考虑下方和右侧的节点。首先初始化 dp 数组最后一个元素是右下角的元素值,然后我们向左移更新每个 dp(j) 为:
dp(j)=grid(i,j)+min(dp(j),dp(j+1))
我们对于每一行都重复这个过程,然后向上一行移动,计算完成后 dp(0) 就是最后的结果。
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]
优化
直接在数组上修改,减少空间复杂度