题目及测试
package pid064;
/*64. 最小路径和
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
*/
import java.util.List;
public class main {
public static void main(String[] args) {
int[][] testTable = {{1,3,1},{1,5,1},{4,2,1}};
test(testTable);
}
private static void test(int[][] ito) {
Solution solution = new Solution();
int rtn;
long begin = System.currentTimeMillis();
for(int i=0;i<ito.length;i++){
for(int j=0;j<ito[0].length;j++){
System.out.print( ito[i][j]+" ");
}
System.out.println();
}
System.out.println();
//开始时打印数组
rtn = solution.minPathSum(ito);//执行程序
long end = System.currentTimeMillis();
System.out.println("rtn="+rtn);
System.out.println();
System.out.println("耗时:" + (end - begin) + "ms");
System.out.println("-------------------");
}
}
解法1(成功,3ms,极快)
我们完全不需要建立 dp 矩阵浪费额外空间,直接遍历 grid[i][j]修改即可。这是因为:grid[i][j] = min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j] ;原 grid 矩阵元素中被覆盖为 dp 元素后(都处于当前遍历点的左上方),不会再被使用到。
首先改造第一行和第一列,逐个递加即可。然后剩余的ij,比较(i-1) (i,j-1)的大小,那个小就那个+自己,即可。最后返回(row-1,col-1)
package pid064;
class Solution {
public int minPathSum(int[][] grid) {
int row=grid.length;
if(row == 0){
return 0;
}
int col=grid[0].length;
if(col == 0){
return 0;
}
// 将grid从(i,j)的大小改造成到(i,j)的最短距离(包括ij)
// 第一行
for(int j=1;j<col;j++){
grid[0][j] = grid[0][j-1] + grid[0][j];
}
// 第一列
for(int i=1;i<row;i++){
grid[i][0] = grid[i-1][0] + grid[i][0];
}
for(int i=1;i<row;i++){
for(int j=1;j<col;j++){
if(grid[i-1][j]<grid[i][j-1]){
grid[i][j] = grid[i-1][j] + grid[i][j];
}else{
grid[i][j] = grid[i][j-1] + grid[i][j];
}
}
}
return grid[row-1][col-1];
}
}