解法:动态规划(非原地修改)
思想:
●状态定义:dp[i][j]
为以grid[i - 1][j - 1]
为结尾的路径的最大值
●转移方程:到当前点只能从上面和左边来,所以选两者中最大的。
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
●初始状态:新建双层vector比grid大一行一列,在上边和左边加了一排0,所以dp[i][j]
对应着grid[i - 1][j - 1]
●返回值:返回dp[m][n]
复杂度:
●时间:O(m*n),每个点遍历一次
●空间:O(m*n),新建dp数组,可以优化(见下方)
代码:
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
if(grid.size() == 0 || grid[0].size() == 0)
return 0;
int m = grid.size(), n = grid[0].size();
//m + 1, n + 1
vector<vector<int>>dp(m + 1, vector<int>(n + 1, 0));
//双层循环更新
for(int i = 1; i <= m; ++i)
for(int j = 1; j <= n; ++j){
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + grid[i - 1][j - 1];
}
return dp[m][n];
}
};
优化:滚动数组,空间优化至O(n)
因为求当前点的值只需要知道上一行和左边的值,所以可以用滚动数组来优化
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
if(grid.size() == 0 || grid[0].size() == 0)
return 0;
int m = grid.size(), n = grid[0].size();
//建立一维dp
vector<int>dp(n + 1, 0);
for(int i = 1; i <= m; ++i)
for(int j = 1; j <= n; ++j){
//该句执行前dp[j]还是上一行的值,而dp[j - 1]是当前行左边的值
dp[j] = max(dp[j - 1], dp[j]) + grid[i - 1][j - 1];
}
return dp[n];
}
};
解法:动态规划(原地修改)
思想:
在边界时只能通过左边或者上边中的一个到达
复杂度:
●时间:O(m*n),每个点遍历一次
●空间:O(1)
代码:
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
if(grid.size() == 0 || grid[0].size() == 0)
return 0;
int m = grid.size(), n = grid[0].size();
//原地修改,不能用dp[i][j]对应grid[i - 1][j - 1],所以需要判断特殊情况
for(int i = 0; i < m; ++i)
for(int j = 0; j < n; ++j){
if(i == 0 && j == 0)
continue;
else 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 - 1][j], grid[i][j - 1]);
}
return grid[m - 1][n - 1];
}
};
我的解法:DFS(能用但是效率太低,所以还是用动态规划)
思想:DFS
复杂度:
●时间:遍历O(n)个节点,每个节点花费O(n)
代码:
class Solution {
private:
int max_gift = 0;
public:
int maxValue(vector<vector<int>>& grid) {
if(grid.empty() || grid[0].empty())
return 0;
dfs(grid, 0, 0, 0);
return max_gift;
}
//cur_gift不能传引用,防止互相干扰
void dfs(vector<vector<int>>& grid, int row, int column, int cur_gift){
//溢出判断
if(row < 0 || row >= grid.size() || column < 0 || column >= grid[0].size())
return;
cur_gift += grid[row][column];
//到右下角来比较
if(row == (grid.size() - 1) && column == (grid[0].size() - 1))
max_gift = max(cur_gift, max_gift);
dfs(grid, row + 1, column, cur_gift);
dfs(grid, row, column + 1, cur_gift);
}
};