很明显又是dp,我们防止越界先将第一行和第一列全部初始化,第一行的初始化值就是自己左边的和加上自身,第一列类似。因为是找最小路径和,所以我们的转移方程是,左边和上边较小的那个值+自身
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
//和上一题很像,dp
if(grid.size() == 0 || grid[0].size() == 0) return 0;
vector<vector<int>> dp(grid.size(),vector<int>(grid[0].size()));
dp[0][0] = grid[0][0];
//防止越界,直接给边界赋值
//其实根本不用dp数组,直接原地修改
for(int i = 1; i < grid.size(); ++i){
dp[i][0] = dp[i-1][0]+grid[i][0];
}
for(int i = 1; i < grid[0].size(); ++i){
dp[0][i] = dp[0][i-1]+grid[0][i];
}
for(int i = 1; i < grid.size(); ++i){
for(int j = 1; j < grid[0].size(); ++j){
dp[i][j] = min(dp[i][j-1],dp[i-1][j])+grid[i][j];
}
}
return dp[grid.size()-1][grid[0].size()-1];
}
};
甚至可以直接在原数组上改
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
//从左上到右下
//二维dp,dp[i][j]取决于dp[i-1][j]和dp[i][j-1]谁比较小
//初始化数组很重要,第0行和第0列先初始化
//其实可以直接在原数组上改
// vector<vector<int>> dp(grid.size(),vector<int>(grid[0].size()));
// dp[0][0] = grid[0][0];
for(int i = 1; i < grid.size(); ++i){
grid[i][0] += grid[i-1][0];
}
for(int j = 1; j < grid[0].size(); ++j){
grid[0][j] += grid[0][j-1];
}
for(int i = 1; i < grid.size(); ++i){
for(int j = 1; j < grid[0].size(); ++j){
grid[i][j] = min(grid[i-1][j],grid[i][j-1])+grid[i][j];
}
}
return grid[grid.size()-1][grid[0].size()-1];
}
};