题解
给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
数据范围
m == grid.length
n == grid[i].length
1 <= m, n <= 200
0 <= grid[i][j]<= 200
测试用例
示例1

java
输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。
示例 2:
java
输入:grid = [[1,2,3],[4,5,6]]
输出:12
题解(时空omn)
java
class Solution {
public int minPathSum(int[][] grid) {
int m=grid.length;
int n=grid[0].length;
int dp[][]=new int[m][n];
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
dp[i][j]=grid[i][j];
if(i-1>=0&&j-1>=0)
dp[i][j]+=Math.min(dp[i-1][j],dp[i][j-1]);
else if(i-1>=0&&j-1<0)
dp[i][j]+=dp[i-1][j];
else if(i-1<0&&j-1>=0){
dp[i][j]+=dp[i][j-1];
}
}
}
return dp[m-1][n-1];
}
}
题解2(原地算法 时间同上,空间O1)
java
class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (i == 0 && j == 0) {
continue; // 起点保持不变
} else if (i == 0) {
// 只能从左边走过来 (第一行)
grid[i][j] += grid[i][j - 1];
} else if (j == 0) {
// 只能从上边走过来 (第一列)
grid[i][j] += grid[i - 1][j];
} else {
// 取从上方和从左方过来的最小值,加上当前格子的值
grid[i][j] += Math.min(grid[i - 1][j], grid[i][j - 1]);
}
}
}
return grid[m - 1][n - 1];
}
}
题解3(时间同上,空间On)
java
class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[] dp = new int[n];
// 初始化第一个元素
dp[0] = grid[0][0];
// 初始化第一行
for (int j = 1; j < n; j++) {
dp[j] = dp[j - 1] + grid[0][j];
}
for (int i = 1; i < m; i++) {
// 每处理新的一行时,第一列只能由其正上方的值累加得到
dp[0] += grid[i][0];
for (int j = 1; j < n; j++) {
// dp[j] (上方的值) 和 dp[j-1] (左方的值) 进行比较
dp[j] = Math.min(dp[j], dp[j - 1]) + grid[i][j];
}
}
return dp[n - 1];
}
}
思路
这道题相当简单,博客中列出了两个相较于官解进阶一点空间复杂度,也不难。就不多讲了。