在一个 N × N 的方形网格中,每个单元格有两种状态:空(0)或者阻塞(1)。
一条从左上角到右下角、长度为 k 的畅通路径,由满足下述条件的单元格 C_1, C_2, …, C_k 组成:
相邻单元格 C_i 和 C_{i+1} 在八个方向之一上连通(此时,C_i 和 C_{i+1} 不同且共享边或角)
C_1 位于 (0, 0)(即,值为 grid[0][0])
C_k 位于 (N-1, N-1)(即,值为 grid[N-1][N-1])
如果 C_i 位于 (r, c),则 grid[r][c] 为空(即,grid[r][c] == 0)
返回这条从左上角到右下角的最短畅通路径的长度。如果不存在这样的路径,返回 -1 。
输入:[[0,1],[1,0]]
输出:2
输入:[[0,0,0],[1,1,0],[1,1,0]]
输出:4
标准的bfs模板
class Solution {
public int shortestPathBinaryMatrix(int[][] grid) {
if (grid == null || grid.length == 0 || grid[0].length == 0) {
return -1;
}
// 如果起点就阻塞那就玩完啦
if (grid[0][0]==1){
return -1;
}
//定义 8个方向
int[][] dir = {{1, -1}, {1, 0}, {1, 1}, {0,-1},{0,1},{-1,-1},{-1,0},{-1,1}};
int m = grid.length;
int n = grid[0].length;
//bfs的老套路 来个队列
Queue<int[]> queue = new LinkedList<>();
queue.add(new int[]{0,0}); //把起点扔进去
grid[0][0] = 1; // 把起点标记为阻塞
int path = 1; // 层数
while (!queue.isEmpty()){
int size = queue.size();
while(size-- > 0){
int[] cur = queue.poll();
int x = cur[0];
int y = cur[1];
//能放进队列里的都是为0可以走的(这一点在后面保证了)
// 如果等于终点则返回
if (x == m-1 && y == n-1){ //
return path;
}
//开始八个方向的判断
for (int[] d : dir){
int x1 = x + d[0];
int y1 = y + d[1];
//这里开始过滤
if (x1 < 0 || x1 >= m || y1 < 0||y1>=m || grid[x1][y1]==1){
continue;
}
//把在数组范围内 并且为0不阻塞的放入队列中
queue.add(new int[]{x1,y1});
grid[x1][y1] = 1; // 标记
}
}
path++; //遍历完一层 这时候要 ++啦
}
return -1;
}
}
自己写的bfs
class Solution {
public int shortestPathBinaryMatrix(int[][] grid) {
if(grid[0][0]==1) return -1;
int[] x_size={0,0,-1,1,1,1,-1,-1};
int[] y_size={-1,1,0,0,1,-1,1,-1};
int[][] temp=new int[grid.length][grid[0].length];
Queue<Integer> queue1=new LinkedList<>();
Queue<Integer> queue2=new LinkedList<>();
queue1.add(0);
queue2.add(0);
grid[0][0]=-1;
while(!queue1.isEmpty()){
int x=queue1.poll();
int y=queue2.poll();
if(x==grid.length-1 && y==grid[0].length-1) return -grid[x][y];
for(int i=0;i<=7;i++){
int xx=x_size[i]+x;
int yy=y_size[i]+y;
if(xx<0 || yy<0 || xx>=grid.length || yy>=grid[0].length) continue;
if(grid[xx][yy]==0){
queue1.add(xx);
queue2.add(yy);
grid[xx][yy]=grid[x][y]-1;
}
}
}
return -1;
}
}
dfs也可以做,就是超时了,grid.length大了之后就会超时。明显不如bfs快,几个测试都没问题,仅供参考。
class Solution {
int[][] grid;
int ans=0x7fffffff;
public int shortestPathBinaryMatrix(int[][] grid) {
this.grid=grid;
dfs(0,0,1);//num=1表示第一步
return ans==0x7fffffff?-1:ans;
}
public void dfs(int i,int j,int num){
if(i<0 || j<0 || i>=grid.length || j>=grid[0].length || grid[i][j]!=0){
return ;
}
if(i==grid.length-1 && j==grid[0].length-1){//到达了右下角
if(num<ans) ans=num;//判断,并替换最优值
return ;
}
grid[i][j]=1;//做标记防止二次访问
dfs(i+1,j,num+1);
dfs(i-1,j,num+1);
dfs(i,j+1,num+1);
dfs(i,j-1,num+1);
dfs(i-1,j-1,num+1);
dfs(i+1,j+1,num+1);
dfs(i-1,j+1,num+1);
dfs(i+1,j-1,num+1);
grid[i][j]=0;//标记变回去
}
}