啊,又是一道dp的题目呢,相信这里的状态转移方程我们可以很直观地写出来:
写到这里,我们能很快写出代码,但是其实边界条件也应该写进来,想想就知道了,获取题目信息之后,我们知道,在答案的矩阵的第一行和第一列都应该是对应行和列的累加和,然后进行自底向上的代码书写
代码也能很快写出来:
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
vector<vector<int>>ans(grid.size(),vector<int>(grid[0].size(),0));
for(int i=0;i<grid.size();++i)
{
if(i==0)
{
ans[i][0]=grid[i][0];
continue;
}
ans[i][0]=ans[i-1][0]+grid[i][0];
}
for(int i=1;i<grid[0].size();++i)
{
ans[0][i]=ans[0][i-1]+grid[0][i];
}
int row=grid.size();
int col=grid[0].size();
for(int i=1;i<row;++i)
{
for(int j=1;j<col;++j)
{
ans[i][j]=max(ans[i-1][j],ans[i][j-1])+grid[i][j];
}
}
return ans[row-1][col-1];
}
};
结果如下所示:
emmm,当然,我们应当想到用滑动数组来简化空间复杂度。这里我们在计算一行时其实只用了上一行以及当前行的前一个,所以我们能将O(n^2)降成O(n)代码如下所示:
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
vector<int>ans(grid[0].size(),0);
ans[0]=grid[0][0];
for(int i=1;i<grid[0].size();++i)
{
ans[i]=ans[i-1]+grid[0][i];
}
int row=grid.size();
int col=grid[0].size();
for(int i=1;i<row;++i)
{
for(int j=0;j<col;++j)
{
if(j==0) ans[0]=ans[0]+grid[i][0];
else
{
ans[j]=max(ans[j-1],ans[j])+grid[i][j];
}
}
}
return ans[col-1];
}
};
结果如下所示:
可以看到,内存消耗减少了很多噢。
不过看了下答案,好像直接在grid上面改可以把时间复杂度降为O(1),嘿嘿,不是不行嗷~
在写完自底向上的代码后,我们可以来尝试一下自顶向下(递归)的写法:
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int row=grid.size(),col=grid[0].size();
return f(grid,row-1,col-1);
}
int f(vector<vector<int>>& grid,int i,int j)
{
if(i==0&&j==0)
{
return grid[i][j];
}
else if(i==0)
{
grid[i][j]=f(grid,i,j-1)+grid[i][j];
return grid[i][j];
}
else if(j==0)
{
grid[i][j]=f(grid,i-1,j)+grid[i][j];
return grid[i][j];
}
grid[i][j]=max(f(grid,i-1,j),f(grid,i,j-1))+grid[i][j];
return grid[i][j];
}
};
结果是这样:
呜呜呜 不知道哪里错了。。。然后试着加了个访问的数组:
class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int row=grid.size(),col=grid[0].size();
vector<vector<int>> visit(row,vector<int>(col,0));
return f(grid,visit,row-1,col-1);
}
int f(vector<vector<int>>& grid,vector<vector<int>>& visit,int i,int j)
{
if(i==0&&j==0)
{
visit[0][0]=1;
return grid[i][j];
}
else if(visit[i][j]==1) return grid[i][j];
else if(i==0)
{
grid[i][j]=f(grid,visit,i,j-1)+grid[i][j];
visit[i][j]=1;
return grid[i][j];
}
else if(j==0)
{
grid[i][j]=f(grid,visit,i-1,j)+grid[i][j];
visit[i][j]=1;
return grid[i][j];
}
grid[i][j]=max(f(grid,visit,i-1,j),f(grid,visit,i,j-1))+grid[i][j];
visit[i][j]=1;
return grid[i][j];
}
};
结果是这样:
啊,所以那个错了的原因我猜测是对于同一个i,j,可能重复求了多次值导致结果错误,如果猜测的不对恳请大佬们指点俺......