class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
vector<vector<int>> dp(grid);
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(i==0&&j==0){continue;}
if(j==0){dp[i][j] = dp[i-1][j]+grid[i][j];}
else if(i==0){dp[i][j] = dp[i][j-1]+grid[i][j];}
else{
dp[i][j] = max(dp[i][j-1],dp[i-1][j])+grid[i][j];
}
}
}
return dp[m-1][n-1];
}
};
//如果使dp的行和列增加一个,这样就不用考虑到边缘的情况了
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
//动态规划表格多一行一列,避免边缘判断,i,j需要从1判断起
vector<vector<int>> dp(m+1,vector<int>(n+1,0));
for(int i=1;i<m+1;i++){
for(int j=1;j<n+1;j++){
//if(i==0&&j==0){continue;}
//if(j==0){dp[i][j] = dp[i-1][j]+grid[i][j];}
//else if(i==0){dp[i][j] = dp[i][j-1]+grid[i][j];}
// else{
// dp[i][j] = max(dp[i][j-1],dp[i-1][j])+grid[i][j];
// }
dp[i][j] = max(dp[i][j-1],dp[i-1][j])+grid[i-1][j-1];
}
}
return dp[m][n];
}
};
优化
由于 dp[i][j]dp[i][j] 只与 dp[i-1][j], dp[i][j-1] , grid[i][j] 有关系,因此可以将原矩阵 gridgrid 用作 dpdp 矩阵,即直接在 gridgrid 上修改即可。应用下方法可省去 dp 矩阵使用的额外空间,因此空间复杂度从 O(MN)降至 O(1) 。
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(i == 0 && j == 0) continue;
if(i == 0) grid[i][j] += grid[i][j - 1] ;
else if(j == 0) grid[i][j] += grid[i - 1][j];
else grid[i][j] += max(grid[i][j - 1], grid[i - 1][j]);
}
}
return grid[m - 1][n - 1];
}
};
//当 gridgrid 矩阵很大时, i = 0i=0 或 j = 0j=0 的情况仅占极少数,相当循环每轮都冗余了一次判断。因此,可先初始化矩阵第一行和第一列,再开始遍历递推。
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
for(int j = 1; j < n; j++) // 初始化第一行
grid[0][j] += grid[0][j - 1];
for(int i = 1; i < m; i++) // 初始化第一列
grid[i][0] += grid[i - 1][0];
for(int i = 1; i < m; i++)
for(int j = 1; j < n; j++)
grid[i][j] += max(grid[i][j - 1], grid[i - 1][j]);
return grid[m - 1][n - 1];
}
};