题目链接
迷宫中离入口最近的出口
题目描述
注意点
- maze[i][j] 要么是 ‘.’ ,要么是 ‘+’
 - entrance.length == 2
 - entrance 一定是空格子
 - 出口的含义是 maze 边界上的空格子
 - entrance格子不算出口
 
解答思路
- 广度优先遍历找到走i步时所能到达的所有节点位置(相同位置多次遍历需要排除,所以需要使用二维数组visited存储已经到达过的节点)。使用队列存储第i步所能到达的所有位置,先将入口入队,可以向上下左右四个方向进行移动(前提是未出界,移动的位置不是墙,移动的位置没有被遍历过),重复上述过程,直到找到出口或队列中没有元素为止
 - 需要注意的是在移动到新的位置(x, y)将该位置添加到队列时也要同步将visted[x][y]标记为true,而不是出队时才标记,因为相同步数可能由上一步多个点到达该位置,可能会做多次入队出队操作(与一次入队出队操作相同),效率很低
 
代码
class Solution {
    public int nearestExit(char[][] maze, int[] entrance) {
        int res = 0;
        int row = maze.length;
        int col = maze[0].length;
        int[][] direction = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
        boolean[][] visited = new boolean[row][col];
        Deque<int[]> deque = new ArrayDeque<>();
        deque.offerLast(new int[]{entrance[0], entrance[1]});
        visited[entrance[0]][entrance[1]] = true;
        while (!deque.isEmpty()) {
            int size = deque.size();
            for (int i = 0; i < size; i++) {
                int[] loc = deque.pollFirst();
                int x = loc[0], y = loc[1];
                if (isExport(x, y, row, col, entrance)) {
                    return res;
                }
                // 朝着四个方向前进
                for (int j = 0; j < direction.length; j++) {
                    int newX = x + direction[j][0], newY = y + direction[j][1];
                    // 移动的格子未出界、不是墙、未遍历过
                    if (newX >= 0 && newX < row && newY >= 0 && newY < col 
                        && maze[newX][newY] == '.' && !visited[newX][newY]) {
                        deque.offerLast(new int[]{newX, newY});
                        // 入队立马标记为已遍历,防止同一层遍历多次相同位置
                        visited[newX][newY] = true;
                    }
                }
            }
            res++;
        }
        return -1;
    }
    public boolean isExport(int x, int y, int row, int col, int[] entrance) {
        if (x == entrance[0] && y == entrance[1]) {
            return false;
        }
        return x == 0 || y == 0 || x == row - 1 || y == col - 1;
    }
}
 
关键点
- 入口不能作为出口
 - 广度优先遍历的思想
 - 在朝着四个方向前进时,哪些位置不能到达
 - 在到达新位置时,入队的同时还要将visited标记为true
 






















