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; } }