题意:给定一个由非负整数组成的m*n矩阵grid,找到一个从左上角到右下角最小的路径和
思路:动态规划。原本用的递归,结果超时,后来改成动态规划,AC了。。
先上超时代码吧,也算一次总结:
public class Solution{
public int minPathSum(int[][] grid) {
return minSum(0, 0, grid, 0);
}
public int minSum(int i, int j, int[][] grid, int curSum) {
// 除了边界,每个点都有两个选择:向右走或向下走
if(i==grid.length-1 && j==grid[0].length-1) { // 已经走到最右下角了
return curSum+grid[i][j];
}
// 如果右边下边都能走,则挑一个小的走
if(i < grid.length-1 && j < grid[0].length-1) {
return Math.min(minSum(i+1, j, grid, curSum+grid[i][j]), minSum(i, j+1, grid, curSum+grid[i][j]));
}
// 如果当前还没有走到最右边,则可以向右走
if(j < grid[0].length-1) {
return minSum(i, j+1, grid, curSum+grid[i][j]);
}
// 如果当前还没有走到最下边,则可以向下走
if(i < grid.length-1) {
return minSum(i+1, j, grid, curSum+grid[i][j]);
}
return curSum;
}
}
更换思路后,AC代码:
public class Solution {
public int minPathSum(int[][] grid) {
// 方法二:动态规划:动态改变grid每个位置上的元素值
// 每个当前元素值的改变是取min(left, top),以确保当前位置的pathSum最小,同时也舍掉了较大的一条路径
// 先求出第一行和第一列的pathSum
int m = grid.length, n = grid[0].length;
for(int i=1; i<m; i++) { // 先求第一列每个元素位置的pathSum
grid[i][0] += grid[i-1][0];
}
for(int j=1; j<n; j++) {
grid[0][j] += grid[0][j-1];
}
if(m == 1 && n == 1) {
return grid[0][0];
} else if(m == 1) {
return grid[0][n-1];
} else if(n == 1) {
return grid[m-1][0];
}
// 从grid[1][1]开始,通过选择grid[i-1][j] 与grid[i][j-1]较小的一个来得到当前grid[i][j]值
for(int i=1; i<m; i++) {
for(int j=1; j<n; j++) {
grid[i][j] += Math.min(grid[i-1][j], grid[i][j-1]);
}
}
return grid[m-1][n-1];
}
}