题目描述
给你一个 n x n 的二进制矩阵 grid 中,返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径,返回 -1 。

二进制矩阵中的 畅通路径 是一条从 左上角 单元格(即,(0, 0))到 右下角 单元格(即,(n - 1, n - 1))的路径,该路径同时满足下述要求:

路径途经的所有单元格都的值都是 0 。
路径中所有相邻的单元格应当在 8 个方向之一 上连通(即,相邻两单元之间彼此不同且共享一条边或者一个角)。
畅通路径的长度 是该路径途经的单元格总数

解题思路

1. javafx.util.Pair包下的Pair<>类与Map区别

pair保存的是一对key value,而map可以保存多对key value。

2. BFS代码框架

// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
    Queue<Node> q; // 核心数据结构
    Set<Node> visited; // 避免走回头路
    
    q.offer(start); // 将起点加入队列
    visited.add(start);
    int step = 0; // 记录扩散的步数

    while (q not empty) {
        int sz = q.size();
        /* 将当前队列中的所有节点向四周扩散 */
        for (int i = 0; i < sz; i++) {
            Node cur = q.poll();
            /* 划重点:这里判断是否到达终点 */
            if (cur is target)
                return step;
            /* 将 cur 的相邻节点加入队列 */
            for (Node x : cur.adj())
                if (x not in visited) {
                    q.offer(x);
                    visited.add(x);
                }
        }
        /* 划重点:更新步数在这里 */
        step++;
    }
}

代码

    public int shortestPathBinaryMatrix(int[][] grids) {
        int res = 1;
        int m = grids.length, n = grids[0].length;
        int[][] direction = {{1, -1}, {1, 0}, {1, 1}, {0, -1}, {0, 1}, {-1, -1}, {-1, 0}, {-1, 1}};
        if (grids == null || grids.length == 0 || grids[0].length == 0 || grids[n - 1][n - 1] == 1 || grids[0][0] == 1) {
            return -1;
        }
        Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
        queue.add(new Pair<>(0, 0));
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                Pair<Integer, Integer> cur = queue.poll();
                int key = cur.getKey();
                int value = cur.getValue();
                if (grids[key][value] == 1) {
                    continue;
                }
                if (key == m - 1 && value == n - 1) {
                    return res;
                }
                grids[key][value] = 1; // 标记
                for (int[] d : direction) {
                    int i1 = key + d[0];
                    int i2 = value + d[1];
                    if (i1 < 0 || i1 >= m || i2 < 0 || i2 >= n) {
                        continue;
                    }
                    queue.offer(new Pair<>(i1, i2));
                }
            }
            res++;
        }
        return -1;
    }

Q.E.D.