礼物的最大价值(中等)
2020年9月7日
题目来源:力扣
解题
- dfs
第一个想到的方法是dfs,但是超时了
class Solution {
private int max=0;
private int[][] dxy={
{
0,1},{
1,0}};
private boolean[][] flag;
public int maxValue(int[][] grid) {
flag=new boolean[grid.length][grid[0].length];
dfs(grid,0,0,0);
return max;
}
private void dfs(int[][] grid,int x,int y,int value){
if(x==grid.length-1 && y==grid[0].length-1){
//已到达右下角
value+=grid[x][y];
max=Math.max(max,value);
return;
}
flag[x][y]=true;
for(int i=0;i<2;i++){
int new_x=x+dxy[i][0];
int new_y=y+dxy[i][1];
//判断越界条件
if(new_x>=0 && new_x<grid.length && new_y>=0 && new_y<grid[0].length && flag[new_x][new_y]==false){
dfs(grid,new_x,new_y,value+grid[x][y]);
flag[new_x][new_y]=false;
}
}
}
}
- 动态规划
已知每个坐标可从左或上移动得到,但还有特殊情况是,第一行不会由上一行移动得到,第一列不会由左一列移动得到。
class Solution {
public int maxValue(int[][] grid) {
int xlen=grid.length;
int ylen=grid[0].length;
int[][] dp=new int[xlen][ylen];
for(int i=0;i<xlen;i++){
for(int j=0;j<ylen;j++){
if(i==0 && j==0) dp[i][j]=grid[0][0];
else if(i==0 && j!=0) dp[i][j]=dp[i][j-1]+grid[i][j];
else if(i!=0 && j==0) dp[i][j]=dp[i-1][j]+grid[i][j];
else dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1])+grid[i][j];
}
}
return dp[xlen-1][ylen-1];
}
}
- 动态规划plus
原地dp,并初始化左边界和上边界,减少冗余判断
class Solution {
public int maxValue(int[][] grid) {
int xlen=grid.length;
int ylen=grid[0].length;
for(int j=1;j<ylen;j++){
grid[0][j]+=grid[0][j-1];
}
for(int i=1;i<xlen;i++){
grid[i][0]+=grid[i-1][0];
}
for(int i=1;i<xlen;i++){
for(int j=1;j<ylen;j++){
grid[i][j]+=Math.max(grid[i-1][j],grid[i][j-1]);
}
}
return grid[xlen-1][ylen-1];
}
}