题目
思路 递归+回溯
对整个grid回溯,如果越界或已访问过或没有黄金就不进行递归。在递归过程中,访问某节点前设置其为已访问,dfs过后设置它为未访问。
代码一
使用vis数组标记是否访问过。
class Solution {
public:
vector<vector<int>> g;
vector<vector<bool>> vis;
int dirs[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int m,n;
int getMaximumGold(vector<vector<int>>& grid) {
g=grid;
m=grid.size();n=grid[0].size();
vis.resize(m,vector<bool>(n));
int ans=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(grid[i][j]!=0){
vis[i][j]=true;
ans=max(ans,dfs(i,j));
vis[i][j]=false;
}
}
}
return ans;
}
int dfs(int x,int y){
int ans=g[x][y];
for(int i=0;i<4;i++){
int xx=x+dirs[i][0],yy=y+dirs[i][1];
if(xx<0 || xx>=m || yy<0 || yy>=n || g[xx][yy]==0 || vis[xx][yy]) continue;
vis[xx][yy]=true;
ans=max(ans,g[x][y]+dfs(xx,yy));
vis[xx][yy]=false;
}
return ans;
}
};
代码二
把grid[x][y]改成0,标记为已访问。
class Solution {
public:
vector<vector<int>> g;
int dirs[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int m,n,ans=0;
int getMaximumGold(vector<vector<int>>& grid) {
g=grid;
m=grid.size();n=grid[0].size();
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
dfs(i,j,0);
}
}
return ans;
}
void dfs(int x,int y,int gold){
gold+=g[x][y];
ans=max(ans,gold);
int rec=g[x][y];
g[x][y]=0;
for(int i=0;i<4;i++){
int xx=x+dirs[i][0],yy=y+dirs[i][1];
if(xx<0 || xx>=m || yy<0 || yy>=n || g[xx][yy]==0)
continue;
dfs(xx,yy,gold);
}
g[x][y]=rec;
}
};