110.最小路径和
题目
描述
给定一个只含非负整数的m*n网格,找到一条从左上角到右下角的可以使数字和最小的路径。
- 在同一时间只能向下或向右移动一步
样例
example 1:
input: [[1,3,1],[1,5,1],[4,2,1]]
output: 7
example 2:
input: [[1,3,2]]
output: 6
题解
思路
参考学习:https://blog.csdn.net/HappyRocking/article/details/85245979
利用动态规划思想解决问题,动态规划的思想是将一个问题分为若干子问题,通过解决所有子问题来解决整个问题。并且为了节约运行时间,需将每个子问题的结果进行存储,以防重复计算带来的时长浪费。
根据题意,从矩阵(二维数组)左上角仅通过向右或下运动到达右下角,这即为总问题。那么矩阵中的元素大致可分为三类,这是需要处理的三类子问题:
- 第一(零)行的元素:仅能通过第一行元素向右移动到达
- 第一(零)列的元素:仅能通过第一列元素向下移动到达
- 普通位置的元素:通过该元素上方或左方的元素移动到达
所以只要分别解决到达以上三类所有位置的最小路径,并将每一个元素所需的最短到达路径计入另一个矩阵,那么即可得到所有元素的最短路径,也就得到了结果。那么计算三类的最短路径,分别具有如下的递推公式:
# 矩阵第一行的元素
minPathMatrix[i][j] += minPathMatrix[i][j-1]
# 矩阵第一列的元素
minPathMatrix[i][j] += minPathMatrix[i-1][j]
# 矩阵其他位置元素
minPathMatrix[i][j] += min(minPathMatrix[i][j-1],minPathMatrix[i-1][j])
利用以上的递推公式结合下图的通俗解释,即可编写相应程序:
步骤
- 建立一个最短路径矩阵(在未处理前与原矩阵相同);
- 外层遍历:对矩阵进行行遍历;
- 内层遍历:对矩阵进行列遍历;
- 起点元素跳过;
- 第一行元素:更新最短路径矩阵,本元素=本元素+其左元素;
- 第一列元素:更新最短路径矩阵,本元素=本元素+其上元素;
- 普通位置元素:更新最短路径矩阵,本元素=本元素+(其上元素,其左元素)较小者;
- 内层遍历:对矩阵进行列遍历;
- 返回最短路径矩阵的右下角元素
程序
def minPathSum(grid):
len_row = len(grid)
len_column = len(grid[0])
minPathMatrix = grid
for i in range(len_row):
for j in range(len_column):
if i == 0 and j == 0:
continue
elif i == 0 and j != 0:
minPathMatrix[i][j] += minPathMatrix[i][j-1]
elif i != 0 and j == 0:
minPathMatrix[i][j] += minPathMatrix[i-1][j]
else:
minPathMatrix[i][j] += min(minPathMatrix[i][j-1],minPathMatrix[i-1][j])
return minPathMatrix[len_row-1][len_column-1]