2020-03-29 (1162 地图分析)

遍历数组里的每个元素,当元素等于0(为海洋)时,求离该元素最近的1(陆地)的距离,比较每个元素的最近陆地距离,返回最大值。
需注意的点:题目要求全为海洋或全为陆地返回-1

    Queue queue = new LinkedList();
    int[][] grid;
    boolean[][] past;
    public int maxDistance(int[][] grid) {
        this.grid = grid;
        past = new boolean[grid.length][grid[0].length];
        int result = -1;
        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid[0].length; j++){
                if(grid[i][j] == 0){
                    clearPast();
                    queue.clear();
                    int distance = getLongDistance(i, j);
                    result = distance > result ? distance : result;
                }
            }
        } 
        return result;
    }

求离海洋最近陆地的距离:宽度优先搜索,建立队列,不断将队头的元素移除,然后遍历队头四个方向的元素,满足条件则加入队列;遍历方向使用两个向量数组dx, dy实现。
需注意的点:
(1) 遍历方向的循环内,nx和ny要在head[0]和head[1]的基础上做增减
(2) 队列的操作方法:
offer 添加一个元素并返回true 若队列已满,则返回false
poll 移除并返问队列头部的元素 若队列为空,则返回null
peek 返回队列头部的元素 若队列为空,则返回null

public int getLongDistance(int x, int y){
        int[] dx = {-1, 1, 0, 0};
        int[] dy = {0, 0, -1, 1};
        int[] head = {0, 0, 0};
        queue.offer(new int[]{x, y, 0});
        past[x][y] = true;
        while(queue.peek() != null){
            head = queue.poll();
            for(int k = 0; k < 4; k++){
                int nx = head[0] + dx[k];
                int ny = head[1] + dy[k];
                if(nx < 0 || ny < 0 || nx > grid.length -1 || ny > grid[0].length -1){
                    continue;
                }
                if(past[nx][ny]){
                  continue;
                }
               if(grid[nx][ny] == 1){
                   return head[2] + 1;
                }
                past[nx][ny] = true;
                queue.offer(new int[]{nx, ny, head[2] + 1});
            }
         }
        return -1;
    }

代码中除了维护了一个队列,还维护了遍历的数组past,大小和地图一致,初始为false,求距离遍历过程中遍历完一个元素将其对应的位置设为true。求完一个海洋元素的距离之后需要清空队列和充值遍历数组。

public void clearPast(){
        for(int i = 0; i < past.length; i++){
            for(int j = 0; j < past[0].length; j++){
                past[i][j] = false;
            }
        }
    }

需要注意的点:
java填充一维数组可用Arrays的fill方法,在网上看到可以先填充一个维度,再填充整个数组的方法来填充二维数组,尝试过之后运行有些问题,会影响最终结果(因为这个找了好久原因,最后发现是在这里)。因为没有用编译器没法具体调试出的问题,回头再调试下。

boolean[] fillData = new boolean[past.length];
        Arrays.fill(fillData, false);
        Arrays.fill(past, fillData);

这个实现方法的效率比较一般,回头再用图的概念实现一下。

你可能感兴趣的:(2020-03-29 (1162 地图分析))