给你一个 m x n 的网格 grid。网格里的每个单元都代表一条街道。grid[i][j] 的街道可以是:
1 表示连接左单元格和右单元格的街道。
2 表示连接上单元格和下单元格的街道。
3 表示连接左单元格和下单元格的街道。
4 表示连接右单元格和下单元格的街道。
5 表示连接左单元格和上单元格的街道。
6 表示连接右单元格和上单元格的街道。
输入:grid = [[1,1,2]]
输出:false
解释:你会停在 (0, 1),而且无法到达 (0, 2) 。
输入:grid = [[1,1,1,1,1,1,3]]
输出:true
class Solution {
int flag;
int[][] grid;
public boolean hasValidPath(int[][] grid) {
this.grid=grid;
dfs(0,0);
return flag==1?true:false;
}
public void dfs(int i,int j){
if(i==grid.length-1 && j==grid[0].length-1) {
flag=1;
return ;
}
int num=grid[i][j];
grid[i][j]=-1;
switch (num){
case 1:
if(j+1<grid[0].length && (grid[i][j+1]==1 || grid[i][j+1]==3 || grid[i][j+1]==5)) dfs(i,j+1);
if(j-1>=0 && (grid[i][j-1]==1 || grid[i][j-1]==4 || grid[i][j-1]==6)) dfs(i,j-1);
break;
case 2:
if(i+1<grid.length && (grid[i+1][j]==2 || grid[i+1][j]==6 || grid[i+1][j]==5)) dfs(i+1,j);
if(i-1>=0 && (grid[i-1][j]==2 || grid[i-1][j]==3 || grid[i-1][j]==4)) dfs(i-1,j);
break;
case 3:
if(i+1<grid.length && (grid[i+1][j]==2 || grid[i+1][j]==6 || grid[i+1][j]==5)) dfs(i+1,j);
if(j-1>=0 && (grid[i][j-1]==1 || grid[i][j-1]==4 || grid[i][j-1]==6)) dfs(i,j-1);
break;
case 4:
if(j+1<grid[0].length && (grid[i][j+1]==1 || grid[i][j+1]==3 || grid[i][j+1]==5)) dfs(i,j+1);
if(i+1<grid.length && (grid[i+1][j]==2 || grid[i+1][j]==6 || grid[i+1][j]==5)) dfs(i+1,j);
break;
case 5:
if(j-1>=0 && (grid[i][j-1]==1 || grid[i][j-1]==4 || grid[i][j-1]==6)) dfs(i,j-1);
if(i-1>=0 && (grid[i-1][j]==2 || grid[i-1][j]==3 || grid[i-1][j]==4)) dfs(i-1,j);
break;
case 6:
if(i-1>=0 && (grid[i-1][j]==2 || grid[i-1][j]==3 || grid[i-1][j]==4)) dfs(i-1,j);
if(j+1<grid[0].length && (grid[i][j+1]==1 || grid[i][j+1]==3 || grid[i][j+1]==5)) dfs(i,j+1);
break;
}
}
}
BFS
class Solution {
int[][] grid;
public boolean hasValidPath(int[][] grid) {
this.grid=grid;
Queue<Point> queue=new LinkedList<>();
queue.add(new Point(0,0));
while(!queue.isEmpty()){
Point p=queue.poll();
int i=p.x;
int j=p.y;
if(i==grid.length-1 && j==grid[0].length-1) return true;
//[[4,1],[6,1]]这是一个陷阱,所以对于每一个节点,有效的子节点大部分是1个,少部分是2个子节点,所以求子节点不要写成函数的形式
int num=grid[i][j];
grid[i][j]=-1;
switch (num){
case 1:
if(j+1<grid[0].length && (grid[i][j+1]==1 || grid[i][j+1]==3 || grid[i][j+1]==5)) queue.add(new Point(i,j+1));
if(j-1>=0 && (grid[i][j-1]==1 || grid[i][j-1]==4 || grid[i][j-1]==6)) queue.add(new Point(i,j-1));
break;
case 2:
if(i+1<grid.length && (grid[i+1][j]==2 || grid[i+1][j]==6 || grid[i+1][j]==5)) queue.add(new Point(i+1,j));
if(i-1>=0 && (grid[i-1][j]==2 || grid[i-1][j]==3 || grid[i-1][j]==4)) queue.add(new Point(i-1,j));
break;
case 3:
if(i+1<grid.length && (grid[i+1][j]==2 || grid[i+1][j]==6 || grid[i+1][j]==5)) queue.add(new Point(i+1,j));
if(j-1>=0 && (grid[i][j-1]==1 || grid[i][j-1]==4 || grid[i][j-1]==6)) queue.add(new Point(i,j-1));
break;
case 4:
if(j+1<grid[0].length && (grid[i][j+1]==1 || grid[i][j+1]==3 || grid[i][j+1]==5)) queue.add(new Point(i,j+1));
if(i+1<grid.length && (grid[i+1][j]==2 || grid[i+1][j]==6 || grid[i+1][j]==5)) queue.add(new Point(i+1,j));
break;
case 5:
if(j-1>=0 && (grid[i][j-1]==1 || grid[i][j-1]==4 || grid[i][j-1]==6)) queue.add(new Point(i,j-1));
if(i-1>=0 && (grid[i-1][j]==2 || grid[i-1][j]==3 || grid[i-1][j]==4)) queue.add(new Point(i-1,j));
break;
case 6:
if(i-1>=0 && (grid[i-1][j]==2 || grid[i-1][j]==3 || grid[i-1][j]==4)) queue.add(new Point(i-1,j));
if(j+1<grid[0].length && (grid[i][j+1]==1 || grid[i][j+1]==3 || grid[i][j+1]==5)) queue.add(new Point(i,j+1));
break;
}
}
return false;
}
}
public class Point{
int x;
int y;
public Point(int x,int y){
this.x=x;
this.y=y;
}
}