1091. 二进制矩阵中的最短路径

题目:

思路:

【1】什么时候用BFS,什么时候用DFS

1.如果只是要找到某一个结果是否存在,那么DFS会更高效。
因为DFS会首先把一种可能的情况尝试到底,才会回溯去尝试下一种情况,只要找到一种情况,就可以返回了。
但是BFS必须所有可能的情况同时尝试,在找到一种满足条件的结果的同时,也尝试了很多不必要的路径; 

2.如果是要找所有可能结果中最短的,那么BFS回更高效。
因为DFS是一种一种的尝试,在把所有可能情况尝试完之前,无法确定哪个是最短,
所以DFS必须把所有情况都找一遍,才能确定最终答案(DFS的优化就是剪枝,不剪枝很容易超时)。
而BFS从一开始就是尝试所有情况,所以只要找到第一个达到的那个点,那就是最短的路径,可以直接返回了,
其他情况都可以省略了,所以这种情况下,BFS更高效。

 

代码展示:

//超时的DFS
class Solution {
    public int shortestPathBinaryMatrix(int[][] grid) {
        if (grid[0][0] == 1) return -1;
        return shortestPathBinaryMatrix(grid,0,0,1);
    }
    
    // 这里的顺序很重要,优先走斜边的
    // 想斜右下走,斜右上走,斜左上走,斜左下走,向右走,向下走,向上走,向左走
    public int[][] path = new int[][]{{1,1},{-1,1},{-1,-1},{1,-1},{0,1},{1,0},{-1,0},{0,-1}};
    public int shortestPathBinaryMatrix(int[][] grid, int row, int col, int count) {
        // 超出边界的情况和遇到障碍物的情况
        if (row == grid.length || row < 0 || col == grid[0].length || col < 0 || grid[row][col] == 1) return -1;
        // 满足条件的情况
        if (row == grid.length-1 && col == grid[0].length-1 && grid[row][col] == 0) return count;
        int res = Integer.MAX_VALUE;
        for (int[] p : path){
            int newRow = row+p[0] , newCol = col+p[1];
            // 走过的路要堵死
            grid[row][col] = 1;
            int tem = shortestPathBinaryMatrix(grid,newRow,newCol,count+1);
            // 回退的时候要将堵死的路清开
            grid[row][col] = 0;
            if (tem > 0){
                res = Math.min(res,tem);
            }
        }
        return res == Integer.MAX_VALUE ? -1 : res;
    }
}


//可用的BFS
//时间11 ms 击败 82.24%
//内存43.4 MB 击败 36.30%
class Solution {
    public int shortestPathBinaryMatrix(int[][] grid) {
        int n = grid.length;
        if(grid[0][0] == 1 || grid[n-1][n-1] == 1){  // 只有两端都是0才可以开始
            return -1;
        }
        int count = 0;
        int[] dx = {0,1,0,-1,1,-1,1,-1};
        int[] dy = {1,0,-1,0,1,-1,-1,1}; // 8个位置
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{0,0});
        grid[0][0] = 1; // 走过的标记为1,这样就可以走最短的了
        while(!queue.isEmpty()){ // 进入BFS
            int size = queue.size();
            count++;
            for(int i = 0; i < size; i++){ // 逐层搜索
                int[] tmp = queue.poll();
                int x = tmp[0];
                int y = tmp[1];
                if(x == n-1 && y == n-1){ // 到达终点就返回
                    return count;
                }
                for(int k = 0; k < 8; k++){
                    int xx = x + dx[k];
                    int yy = y + dy[k];
                    if(xx >= 0 && xx < n && yy >= 0 && yy < n && grid[xx][yy] == 0){  // 加入下一层的数
                        queue.offer(new int[]{xx,yy});
                        grid[xx][yy] = 1;
                    }
                }
            }
        } 
        return -1; 
    }
}
posted @ 2023-07-31 17:46  忧愁的chafry  阅读(12)  评论(0编辑  收藏  举报