给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。
DFS又超时了
class Solution {
int ans=0x7fffffff;
public int minPathSum(int[][] grid) {
dfs(0,0,grid,0);
return ans;
}
void dfs(int i,int j,int[][] grid,int sum){
if(i<0 || j<0 || i>=grid.length || j>=grid[0].length){
return ;
}
if(i==grid.length-1 && j==grid[0].length-1){
if(sum+grid[i][j]<ans) ans=sum+grid[i][j];
return ;
}
if(sum+grid[i][j]<=ans){
dfs(i,j+1,grid,sum+grid[i][j]);
dfs(i+1,j,grid,sum+grid[i][j]);
}
}
}
dfs函数返回的是终点到该点所有路径的最小值
DFS+记忆搜索
class Solution {
int[][] grid;
int[][] temp;
public int minPathSum(int[][] grid) {
this.grid=grid;
temp=new int[grid.length][grid[0].length];
for(int i=0;i<grid.length;i++){
for(int j=0;j<grid[0].length;j++){
temp[i][j]=-1;
}
}
dfs(0,0);
return temp[0][0];
}
int dfs(int i,int j){
if(i<0 || j<0 || i>=grid.length || j>=grid[0].length){
return 0x7fffffff;
}
if(temp[i][j]!=-1) return temp[i][j];
if(i==grid.length-1 && j==grid[0].length-1){
temp[i][j]=grid[i][j];
return grid[i][j];
}
int right=dfs(i,j+1);
int down=dfs(i+1,j);
temp[i][j]=grid[i][j]+(down<right?down:right);
return temp[i][j];
}
}
DP代码
class Solution {
public int minPathSum(int[][] grid) {
for(int j=1;j<grid[0].length;j++) grid[0][j]+=grid[0][j-1];
for(int i=1;i<grid.length;i++) grid[i][0]+=grid[i-1][0];
for(int i=1;i<grid.length;i++){
for(int j=1;j<grid[0].length;j++){
grid[i][j]+=Math.min(grid[i][j-1],grid[i-1][j]);
}
}
return grid[grid.length-1][grid[0].length-1];
}
}