lintcode 1911 · Map analysis [BFS]

topic

https://www.lintcode.com/problem/1911

你现在手里有一份大小为 N x N 的网格grid,上面的每个单元格都用 01 标记好了。其中 0 代表海洋,1 代表陆地,请你找出一个海洋单元格,这个海洋单元格到离它最近的陆地单元格的距离是最大的。
我们这里说的距离是「曼哈顿距离」( Manhattan Distance):(x0, y0)(x1, y1) 这两个单元格之间的距离是 |x0 - x1| + |y0 - y1| 。
如果网格上只有陆地或者海洋,请返回 -11 <= grid.length == grid[0].length <= 100
grid[i][j] 不是 0 就是 1

样例
样例 1:

输入: 
[[1,0,1],[0,0,0],[1,0,1]]
输出: 
2
解释: 
海洋单元格 (1, 1) 和所有陆地单元格之间的距离都达到最大,最大距离为 2。
样例 2:

输入: 
[[1,0,0],[0,0,0],[0,0,0]]
输出: 
4
解释: 
海洋单元格 (2, 2) 和所有陆地单元格之间的距离都达到最大,最大距离为 4

Ideas

    解法:多起点bfs
    算法 / 数据结构:BFS
    解题思路
    一开始的时候就把小岛加入队列,标记加入队列的小岛,一轮一轮扩展,
    进行Bfs遍历,队列中最后一个被找到的位置,就是所求的答案。
    复杂度分析
    时间复杂度:O(n^2)
    该算法考虑最坏情况下,所有的区域都是海洋,那么每一个区域都会进行 BFS。程序的总的时间复杂度是 O(n^2)。
    空间复杂度:O(n^2)
    二位数组的大小是n^2

code

public class Solution {
    
    
    /**
     * @param grid: An array.
     * @return: An integer.
     */
    public int maxDistance(int[][] grid) {
    
    
     /*
        解法:多起点bfs
        算法 / 数据结构:BFS
        解题思路
        一开始的时候就把小岛加入队列,标记加入队列的小岛,一轮一轮扩展,
        进行Bfs遍历,队列中最后一个被找到的位置,就是所求的答案。
        复杂度分析
        时间复杂度:O(n^2)
        该算法考虑最坏情况下,所有的区域都是海洋,那么每一个区域都会进行 BFS。程序的总的时间复杂度是 O(n^2)。
        空间复杂度:O(n^2)
        二位数组的大小是n^2
         */

        int[][] dirx = {
    
    {
    
    -1,0},{
    
    1,0},{
    
    0,-1},{
    
    0,1}};
        Queue<int[]> q = new LinkedList<>();
        Set<Integer> visited = new HashSet<>();
        int n = grid.length,m= grid[0].length;
        for (int i = 0; i <n ; i++) {
    
    
            for (int j = 0; j <m ; j++) {
    
    
                if(grid[i][j] ==1){
    
    
                    q.add(new int[]{
    
    i,j});
                    visited.add(i*m+j);
                }
            }
        }
        
        if(q.size() == n*m  || q.size() ==0) return -1;  //全是陆地或者海洋

        int step = 0;
        while (!q.isEmpty()){
    
    
            step++;
            int qlen = q.size();
            for (int k = 0; k <qlen ; k++) {
    
    
                int[] arr = q.poll();
                int x = arr[0],y=arr[1];
                for (int[] dir : dirx) {
    
    
                    int x1 = x+dir[0],y1=y+dir[1];
                    if(x1 >=0 && x1<n && y1>=0 && y1< m && grid[x1][y1] ==0){
    
    
                        if(visited.contains(x1*m+y1))
                            continue;

                        q.add(new int[]{
    
    x1,y1});
                        visited.add(x1*m+y1);
                    }
                }
            }
        }

        return step ==0 ? -1:step-1;
    }
}

Guess you like

Origin blog.csdn.net/weixin_37991016/article/details/132782887