[Leedcode] [JAVA] [1162 title] [BFS]

【Problem Description】

你现在手里有一份大小为 N x N 的『地图』(网格) grid,上面的每个『区域』(单元格)都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地,你知道距离陆地区域最远的海洋区域是是哪一个吗?请返回该海洋区域到离它最近的陆地区域的距离。

我们这里说的距离是『曼哈顿距离』( Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个区域之间的距离是 |x0 - x1| + |y0 - y1| 。

如果我们的地图上只有陆地或者海洋,请返回 -1。

 

示例 1:
![image.png](https://upload-images.jianshu.io/upload_images/17025746-537539d18cf50a49.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)



输入:[[1,0,1],[0,0,0],[1,0,1]]
输出:2

提示:

1 <= grid.length == grid[0].length <= 100
grid[i][j] 不是 0 就是 1


Example 1:
Input: [[1,0,1], [0,0,0], [1,0,1]]
Output: 2
Example 1
Explanation: the distance between the sea area (1, 1) and all land areas We have reached the maximum, a maximum distance of 2.

[Thinking] answer

1. (Whiskers engineering) BFS
  • More land starting point into the queue, the pop-up while groping around, every time the distance +1

Time complexity: O (N ^ 2) space complexity: O (N ^ 2)

 public int maxDistance(int[][] grid) {
            //方向向量
            int [][] directions = {{1,0},{-1,0},{0,1},{0,-1}};

            int N = grid.length;

            Queue<Integer> queue =  new LinkedList<>();

            for(int i= 0 ; i< N; i++){
                for(int j= 0 ; j < N; j++)
            {
                if(grid[i][j]==1){
                    queue.add(getIndex(i,j,N));
                }
            } 
            }

            int size= queue.size();
            //全部是0或者全部是1 全海洋或全陆地
            if(size==0 || size == N*N){
                return -1;
            }

            int step = 0;

            while (!queue.isEmpty()){
                int  currentQueueSize = queue.size();
                for(int i=0 ;i<currentQueueSize;i++){
                    Integer head = queue.poll();
                    //巧妙一个数存放一个二维坐标
                    int currentX =  head / N;
                    int currentY =  head % N;

                    for(int[] direction :directions){
                        int newX = currentX+direction[0];
                        int newY = currentY+direction[1];

                        if(inArea(newX,newY,N) && grid[newX][newY]==0)
                       {
                            //扩充海洋部分  赋值任何非0数 最后只关注最长路径
                            grid[newX][newY] =1;
                            queue.add(getIndex(newX,newY,N));
                        }
                    }
                }
                step++;
            }
            //最后一部没有扩散 但step++仍然执行 故最后结果需要-1
            return step-1;

    }
    /**
     * @param x    二维表格单元格横坐标
     * @param y    二维表格单元格纵坐标
     * @param cols 二维表格列数
     * @return
     */
    private int getIndex(int x, int y, int cols) {
        return x * cols + y;
    }

    /**
     * @param x 二维表格单元格横坐标
     * @param y 二维表格单元格纵坐标
     * @param N 二维表格行数(列数)
     * @return 是否在二维表格有效范围内
     */
    private boolean inArea(int x, int y, int N) {
        return 0 <= x && x < N && 0 <= y && y < N;
    }
作者:liweiwei1419
链接:https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/yan-du-you-xian-bian-li-java-by-liweiwei1419/

###### 2. (sweet aunt's knife) BFS

  • More land starting point into the queue, the pop-up while groping around, every time the distance +1

Time complexity: O (N ^ 2) space complexity: O (N ^ 2)

 public int maxDistance(int[][] grid) {
        int[] dx = {0, 0, 1, -1};
        int[] dy = {1, -1, 0, 0};

        Queue<int[]> queue = new ArrayDeque<>();
        int m = grid.length, n = grid[0].length;
        // 先把所有的陆地都入队。
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == 1) {
                    queue.offer(new int[] {i, j});
                }
            }
        }

        // 从各个陆地开始,一圈一圈的遍历海洋,最后遍历到的海洋就是离陆地最远的海洋。
        boolean hasOcean = false;
        int[] point = null;
        while (!queue.isEmpty()) {
            point = queue.poll();
            int x = point[0], y = point[1];
            // 取出队列的元素,将其四周的海洋入队。
            for (int i = 0; i < 4; i++) {
                int newX = x + dx[i];
                int newY = y + dy[i];
                if (newX < 0 || newX >= m || newY < 0 || newY >= n || grid[newX][newY] != 0) {
                    continue;
                }
                grid[newX][newY] = grid[x][y] + 1; // 这里我直接修改了原数组,因此就不需要额外的数组来标志是否访问
                hasOcean = true;
                queue.offer(new int[] {newX, newY});
            }
        }

        // 没有陆地或者没有海洋,返回-1。
        if (point == null || !hasOcean) {
            return -1;
        }

        // 返回最后一次遍历到的海洋的距离。
        return grid[point[0]][point[1]] - 1;

    }

作者:sweetiee
链接:https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/jian-dan-java-miao-dong-tu-de-bfs-by-sweetiee/

【to sum up】

1. BFS
  • If the subject of the request and returns the results related to the distance, all the elements required once the current list are successively taken out inside the while loop, the number of such "all at once" operation is the distance we need;
  • If a cell is added to the queue later, you need to immediately mark it has access (under the circumstances, can be modified directly on the original input array, you can use a Boolean array visited labeled), or is likely to occur an infinite loop
BFS 2. Tree and undirected graph
  • Only a tree root, a plurality of source points to a non FIG.
  • There is a tree does not need to label you visited, no need to mark the map Have you visited and need to have access (to prevent duplicate node into the team) before the team!
3. Skills in two-dimensional coding table code
  • Setting the direction of an array
int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

int[] dx = {0, 0, 1, -1};
int[] dy = {1, -1, 0, 0};
  • Determining whether the setting function inArea bounds of ()
  • According to circumstances, the use of two-dimensional coordinates and the one-dimensional coordinate conversion operation, since the two-dimensional coordinates when the incoming queue, the need to package an array of arrays to create and destroy a certain performance cost
private int getIndex(int x, int y, int cols) {
       return x * cols + y;
   }
Published 22 original articles · won praise 0 · Views 416

Guess you like

Origin blog.csdn.net/dadongwudi/article/details/105176490