64. Minimum Path Sum
题目意思:给出一个m*n的方格,方格里面的元素是非负数,现在要求你找一条路径,使得从[0][0]到[m-1][n-1]的路径长度最短。官方给出的例子如下:
Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7
根据上面给出的解释,那么我们可以发现从左上到右下的一条最短的路径为(1→3→1→1→1),他们相加的和为7,这就是最短路径。
题目分析:分析这个题目的意思,是需要求解最短的路径(PS:一般出现最小或者最大的这个字眼的时候,都是采用动态规划),那么一般情况下是采用动态规划去解决,动态规划要求利用到上一次的结果,是一种特殊的迭代思想,动态规划的关键是要得到递推关系式。对于本题,从原点到达(i, j)的最小路径等于 :原点到达(i-1, j)最小路径与到达(i, j-1)最小路径中的最小值。即 dp[i][j] = Math.min(dp[i-1][j], dp[i][j-1])+nums[i][j].一般的情况下是写出基本的方案,然后后面再采取优化,先给出基本的动态规划的解题方案:
方案1:基本的解题方案(空间复杂度为O(m*n))
public int minPathSum(int[][] grid) {
// 计算行数
int m = grid.length;
if(m==0)
return 0;
//计算列数
int n = grid[0].length;
if(n==0)
return 0;
int[][] f = new int[m][n];
f[0][0] = grid[0][0];
// 初始化行
for(int i=1;i<m;i++) {
f[i][0] = f[i-1][0] + grid[i][0];
}
// 初始化列
for(int j=1;j<n;j++) {
f[0][j] = f[0][j-1] + grid[0][j];
}
// 求解最短路径
for(int i=1;i<m;i++) {
for(int j=1;j<n;j++) {
f[i][j] = Math.min(f[i-1][j], f[i][j-1]) + grid[i][j];
}
}
return f[m-1][n-1];
}
方案二:优化空间复杂度,使其空间复杂度降低为O(n)
def minPathSum(self, grid):
if not grid:
return 0
r,c=len(grid),len(grid[0])
cur=[0]*c
cur[0]=grid[0][0]
# 初始化工作
for i in range(1,c):
cur[i]=cur[i-1]+grid[0][i]
# DP
for i in range(1,r):
cur[0]+=grid[i][0]
for j in range(1,c):
cur[j]=min(cur[j-1],cur[j])+grid[i][j]
return cur[-1]
PS:自己多动手写几遍DP,从最基本的开始,然后优化,多写几次就能掌握,勤能补拙,加油。

被折叠的 条评论
为什么被折叠?



