clllll  

image

class Solution {
    public int maxDistance(int[][] grid) {
        // 思路:宽度优先遍历。
        // 第一层有一个或者多个。单源+多源。
        // 遍历到每一层的时候,看当前层有多少个数,然后就操作多少次。

        int m = grid.length;
        int n = grid[0].length;
        boolean[][] visited = new boolean[m][n]; // 保存当前节点是否遍历过
        int[][] queue = new int[m * n][2]; // 队列
        int l = 0;
        int r = 0;
        int cnt_0 = 0; // 0的个数。
        // 把所有的1入队。
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    queue[r][0] = i;
                    queue[r++][1] = j;
                    visited[i][j] = true;
                } else {
                    cnt_0++;
                }
            }
        }

        if (cnt_0 == 0 || cnt_0 == n * m) {
            // 全0或者没有0
            return -1;
        }

        int ans = 0;
        int[] next = new int[] { -1, 0, 1, 0, -1 }; // 四个方向移动

        while (l != r) {
            int cur_level = r - l;
            ans++;
            for (int k = 0; k < cur_level; k++) {
                int i = queue[l][0];
                int j = queue[l++][1];
                // 四个方向 入队

                for (int g = 0; g < 4; g++) {
                    int next_i = i + next[g];
                    int next_j = j + next[g + 1];
                    if (next_i >= 0 && next_i < m && next_j >= 0 && next_j < n && !visited[next_i][next_j]) {
                        queue[r][0] = next_i;
                        queue[r++][1] = next_j;
                        visited[next_i][next_j] = true;
                    }
                }
            }
        }
        return ans - 1;

    }
}
posted on 2024-12-18 19:12  llcl  阅读(28)  评论(0)    收藏  举报