C++DFS解法,容易理解
2020年3月22日 12:52
解题思路:
通过构建pipe数组,将每个拼图转化为四个方向上的移动限制图。
例:
pipe[3][2]=3,代表3号拼图可以由向上的方向进入其中,并转向左方向继续前进。
pipe[5][3]=-1,代表5号拼图不可以由向左的方向进入其中。
其中0代表向下、1代表向右、2代表向上、3代表向左、-1代表不可走
![]()
这之后问题就变成了一个简单的DFS了
class Solution {
int m,n,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};//0下、1右、2上、3左
int pipe[7][4]={{-1,-1,-1,-1},{-1,1,-1,3},{0,-1,2,-1},{-1,0,3,-1},{-1,-1,1,0},{3,2,-1,-1},{1,-1,-1,2}};
//记录各个拼图块路径的方向,0、1、2、3代表方向,-1代表不可走。
bool dfs(int x,int y,int dir,vector<vector<int>>& grid){//(x,y,当前方向,地图)
if(x==m-1&&y==n-1) return 1;//到达终点
int xx=x+dx[dir];
int yy=y+dy[dir];//得到下一个准备走的坐标
if(xx<0||yy<0||xx>=m||yy>=n)return 0;//越界
int nxt=grid[xx][yy];//得到下一块拼图的编号
if(pipe[nxt][dir]!=-1)return dfs(xx,yy,pipe[nxt][dir],grid);//如果当前方向可走,则方向改变,继续走。
return 0;//无法走,返回0
}
public:
bool hasValidPath(vector<vector<int>>& grid) {
m=grid.size();
n=grid[0].size();
int sta=grid[0][0];//起点的拼图编号
for(int i=0;i<4;++i)//朝着四个方向都试一下
if(pipe[sta][i]!=-1)//当前方向可以走
if(dfs(0,0,pipe[sta][i],grid))//沿着当前方向搜索
return 1;//拼图都有两个方向可以走,只要沿着一个初始方向走通就可以。
return 0;
}
};
3.23 updata
之前是加了vis数组判断是否访问过的,之后感觉没啥用,就删掉了,发现也能过题目,便没再多想。
这里很感谢@study11 @xm9304同学的质疑
同时很感谢@mapleking同学的指正。
之后,再@LeetCode加一下测试用例。
class Solution {
int m,n,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};//0下、1右、2上、3左
int pipe[7][4]={
{-1,-1,-1,-1},
{-1,1,-1,3},
{0,-1,2,-1},
{-1,0,3,-1},
{-1,-1,1,0},
{3,2,-1,-1},
{1,-1,-1,2}
};
//记录各个拼图块路径的方向,0、1、2、3代表方向,-1代表不可走。
bool vis[302][302];
bool dfs(int x,int y,int dir,vector<vector<int>>& grid){//(x,y,当前方向,地图)
vis[x][y]=1;
if(x==m-1&&y==n-1) return 1;//到达终点
int xx=x+dx[dir];
int yy=y+dy[dir];//得到下一个准备走的坐标
if(xx<0||yy<0||xx>=m||yy>=n)return 0;//越界
int nxt=grid[xx][yy];//得到下一块拼图的编号
if(pipe[nxt][dir]!=-1&&!vis[xx][yy])
return dfs(xx,yy,pipe[nxt][dir],grid);//如果当前方向可走,则方向改变,继续走。
return 0;//无法走,返回0
}
public:
bool hasValidPath(vector<vector<int>>& grid) {
m=grid.size();
n=grid[0].size();
memset(vis,0,sizeof(vis));
int sta=grid[0][0];//起点的拼图编号
for(int i=0;i<4;++i)//朝着四个方向都试一下
if(pipe[sta][i]!=-1)//当前方向可以走
if(dfs(0,0,pipe[sta][i],grid))//沿着当前方向搜索
return 1;//拼图都有两个方向可以走,只要沿着一个初始方向走通就可以。
return 0;
}
};