思想:
方法一:DP
状态方程:
f[i][0] 可以提前求出; 0 <= i < m
f[0][i] 可以提前求出; 0 <= i < n
f[i][j] = min( f[i-1][j], f[i][j-1]) + grid[i][j];
class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> f = vector<vector<int>>(m,vector<int>(n));
int sum = 0;
for(int i=0;i<m;i++) {
sum += grid[i][0];
f[i][0] = sum;
}
sum = f[0][0];
for(int i=1;i<n;i++) {
sum += grid[0][i];
f[0][i] = sum;
}
for(int i=1; i<m; i++) {
for(int j=1; j<n; j++) {
f[i][j] = min(f[i-1][j], f[i][j-1]) + grid[i][j];
}
}
return f[m-1][n-1];
}
};
对上面的DP进行空间复杂度的优化,用一维数组从上往下刷一遍。
class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
int m = grid.size();
int n = grid[0].size();
vector<int> f(n);
fill(f.begin(), f.end(), INT_MAX);
f[0] = 0;
for(int i = 0; i < m; i++) {
f[0] += grid[i][0];
for(int j = 1; j < n; j++) {
f[j] = min(f[j-1], f[j]) + grid[i][j];
}
}
return f[n-1];
}
};方法三:DFS+备忘录
注意:
(1)传grid的时候要传引用,否则会MLE,因为每一次dfs都会创建原grid的副本。
(2)if(x<0 || y<0) 要返回INT_MAX,因为我们要取小。
class Solution {
private:
vector<vector<int>> f;
int getOrUpdate(vector<vector<int>> &grid,int x, int y) {
if(x<0 || y<0) return INT_MAX;
if(f[x][y] >= 0) return f[x][y];
else return f[x][y] = dfs(grid,x,y);
}
int dfs(vector<vector<int>> &grid, int x, int y) {
if(x<0 || y<0) return 0;
if(x==0 && y==0) return grid[0][0];
return min(getOrUpdate(grid, x-1, y), getOrUpdate(grid, x, y-1)) + grid[x][y];
}
public:
int minPathSum(vector<vector<int> > &grid) {
int m = grid.size();
int n = grid[0].size();
this->f = vector<vector<int>>(m,vector<int>(n,-1));
return dfs(grid,m-1,n-1);
}
};
320

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



