【练题记录】leetcode 1091 二进制矩阵中的最短路径

问题描述

在一个 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 。

示例 1:
输入:[[0,1],[1,0]]
在这里插入图片描述
输出:2
在这里插入图片描述
示例 2:
输入:[[0,0,0],[1,1,0],[1,1,0]]
在这里插入图片描述

输出:4
在这里插入图片描述

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-path-in-binary-matrix
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

  • 1、本题目是求最短路径,因此要使用BFS
  • 2、仔细看示例,最左上角的格子已经算是1步了,这里有点误导性,要注意
  • 3、按照BFS算法,使用队列来保存要访问的元素,每次循环对长度+1,比如第一轮循环就遍历左上角的格子的周围8个方向的格子,如果有0,则value设置为1,第二轮循环遍历长度为2的格子的八个方向,一次类推…
  • 4、如果遍历的格子到了最右下角,则说明找到了最短距离,如果队列都为空了,并且还是不是最右下角格子,说明没有路径,返回-1
  • 5、解题思路参考了:https://www.bilibili.com/video/av56067911/ 的部分讲解,实现部分没有细看,感兴趣的可以看看他的实现,或许比我实现得更优雅。

代码实现

public int shortestPathBinaryMatrix(int[][] grid) {

        int gridLineNum = grid.length;
        int gridColNum = grid[0].length;

        if (grid[0][0] == 1 || grid[gridLineNum - 1][gridColNum - 1] == 1) {
            return -1;
        }

        grid[0][0] = 1;
        Queue<GridCell> visitCellQueue = new LinkedBlockingDeque<>();
        visitCellQueue.add(new GridCell(0, 0, 1));
        while (!visitCellQueue.isEmpty()) {
            GridCell cellToCheck = visitCellQueue.poll();
            checkEightDirectionForCell(cellToCheck,grid,visitCellQueue);
            if (cellToCheck.getLine() == grid.length-1 && cellToCheck.getCol() == grid.length-1){
                return cellToCheck.getValue();
            }
        }
        return -1;
    }

    private void checkEightDirectionForCell(GridCell gridCell, int[][] grid, Queue<GridCell> visitCellQueue) {
        //上
        if (gridCell.getLine() - 1 >= 0 && grid[gridCell.getLine() - 1][gridCell.getCol()] == 0) {
            grid[gridCell.getLine() - 1][gridCell.getCol()] = gridCell.getValue() + 1;
            visitCellQueue.add(new GridCell(gridCell.getLine() - 1, gridCell.getCol(), grid[gridCell.getLine() - 1][gridCell.getCol()]));
        }
        //左上
        if (gridCell.getLine() - 1 >= 0 && gridCell.getCol() - 1 >= 0 && grid[gridCell.getLine() - 1][gridCell.getCol() - 1] == 0) {
            grid[gridCell.getLine() - 1][gridCell.getCol() - 1] = gridCell.getValue() + 1;
            visitCellQueue.add(new GridCell(gridCell.getLine() - 1, gridCell.getCol() - 1, grid[gridCell.getLine() - 1][gridCell.getCol() - 1]));
        }
        //左
        if (gridCell.getCol() - 1 >= 0 && grid[gridCell.getLine()][gridCell.getCol() - 1] == 0) {
            grid[gridCell.getLine()][gridCell.getCol() - 1] = gridCell.getValue() + 1;
            visitCellQueue.add(new GridCell(gridCell.getLine(), gridCell.getCol(), grid[gridCell.getLine()][gridCell.getCol() - 1]));
        }
        //左下
        if (gridCell.getLine() + 1 < grid.length && gridCell.getCol() - 1 >= 0 && grid[gridCell.getLine() + 1][gridCell.getCol() - 1] == 0) {
            grid[gridCell.getLine() + 1][gridCell.getCol() - 1] = gridCell.getValue() + 1;
            visitCellQueue.add(new GridCell(gridCell.getLine() + 1, gridCell.getCol() - 1, grid[gridCell.getLine() + 1][gridCell.getCol() - 1]));
        }
        //下
        if (gridCell.getLine() + 1 < grid.length && grid[gridCell.getLine() + 1][gridCell.getCol()] == 0) {
            grid[gridCell.getLine() + 1][gridCell.getCol()] = gridCell.getValue() + 1;
            visitCellQueue.add(new GridCell(gridCell.getLine() + 1, gridCell.getCol(), grid[gridCell.getLine() + 1][gridCell.getCol()]));
        }
        //右下
        if (gridCell.getLine() + 1 < grid.length && gridCell.getCol() + 1 < grid.length && grid[gridCell.getLine() + 1][gridCell.getCol() + 1] == 0) {
            grid[gridCell.getLine() + 1][gridCell.getCol() + 1] = gridCell.getValue() + 1;
            visitCellQueue.add(new GridCell(gridCell.getLine() + 1, gridCell.getCol() + 1, grid[gridCell.getLine() + 1][gridCell.getCol() + 1]));
        }
        //右
        if (gridCell.getCol() + 1 < grid.length && grid[gridCell.getLine()][gridCell.getCol() + 1] == 0) {
            grid[gridCell.getLine()][gridCell.getCol() + 1] = gridCell.getValue() + 1;
            visitCellQueue.add(new GridCell(gridCell.getLine(), gridCell.getCol() + 1, grid[gridCell.getLine()][gridCell.getCol() + 1]));
        }
        //右上
        if (gridCell.getLine() - 1 >= 0 && gridCell.getCol() + 1 < grid.length && grid[gridCell.getLine() - 1][gridCell.getCol() + 1] == 0) {
            grid[gridCell.getLine() - 1][gridCell.getCol() + 1] = gridCell.getValue() + 1;
            visitCellQueue.add(new GridCell(gridCell.getLine() - 1, gridCell.getCol() + 1, grid[gridCell.getLine() - 1][gridCell.getCol() + 1]));
        }
    }

    class GridCell {

        private int line;

        private int col;

        private int value;

        public int getLine() {
            return line;
        }

        public void setLine(int line) {
            this.line = line;
        }

        public int getCol() {
            return col;
        }

        public void setCol(int col) {
            this.col = col;
        }

        public int getValue() {
            return value;
        }

        public void setValue(int value) {
            this.value = value;
        }

        public GridCell(int line, int col, int value) {
            this.line = line;
            this.col = col;
            this.value = value;
        }
    }
发布了45 篇原创文章 · 获赞 8 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/iNiegang/article/details/104119939