从数组的左上角到右下角,求经过的路径的最小和。
思路:
(1)状态设定:f[x][y]为从坐标(0,0)走到(x,y)的最短路径和
(2)状态方程为:f[x][y] = (x,y) + min{f[x-1][y], f[x][y-1]};
(3)初始化:f[0][0] = grid[0][0];f[i][0] = sum(0,0 —> i,0);f[0][i] = sum(0,0 —> 0,i)
(4)结果:f[m-1][n-1];
class Solution {
public:
int minPathSum(vector<vector<int> > &grid) {
if(grid.empty() || grid[0].empty())
return 0;
int m = grid.size();
int n = grid[0].size();
vector<vector<int> > ret(m, vector<int>(n,0));
ret[0][0] = grid[0][0];
for(int i = 1; i < m; ++i)
ret[i][0] = grid[i][0] + ret[i-1][0];
for(int i = 1; i < n; ++i)
ret[0][i] = grid[0][i] + ret[0][i-1];
for(int i = 1; i < m; ++i){
for(int j = 1; j < n; ++j){
ret[i][j] = grid[i][j] + min(ret[i-1][j], ret[i][j-1]);
}
}
return ret[m-1][n-1];
}
};
上面是没有对grid进行修改,下面这个是直接在grid上面做手脚
int minPathSum(vector<vector<int> > &grid) {
if(grid.empty() || grid[0].empty())
return 0;;
int M = grid.size();
int N = grid[0].size();
for(int i = 0; i < M; ++i){
for(int j = 0; j < N; ++j){
if(i == 0 && j != 0) grid[i][j] += grid[i][j-1];
if(i != 0 && j == 0) grid[i][j] += grid[i-1][j];
if(i*j != 0)
grid[i][j] += min(grid[i-1][j], grid[i][j-1]);
}
}
return grid[M-1][N-1];
}