【leetcode】【medium】【每日一題】1162. As Far from Land as Possible

1162. As Far from Land as Possible

Given an N x N grid containing only values 0 and 1, where 0 represents water and 1 represents land, find a water cell such that its distance to the nearest land cell is maximized and return the distance.

The distance used in this problem is the Manhattan distance: the distance between two cells (x0, y0) and (x1, y1) is |x0 - x1| + |y0 - y1|.

If no land or water exists in the grid, return -1.

Example 1:

 

Input: [[1,0,1],[0,0,0],[1,0,1]]
Output: 2
Explanation: 
The cell (1, 1) is as far as possible from all the land with distance 2.

Example 2:

 

Input: [[1,0,0],[0,0,0],[0,0,0]]
Output: 4
Explanation: 
The cell (2, 2) is as far as possible from all the land with distance 4.

Note:

  1. 1 <= grid.length == grid[0].length <= 100
  2. grid[i][j] is 0 or 1

題目鏈接:https://leetcode-cn.com/problems/as-far-from-land-as-possible/

 

思路

法一:多源BFS

這道題用一般思路想,就是對每個land做一次向四周的water擴散一遍,每次擴散時water所用距離取多次的最小值。時間複雜度是O(n*n*land),這種方法在land多的情況下較慢。

多源BFS就是用於解決這種多個出發點的題目。

多源BFS的形象解釋:https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/zhen-liang-yan-sou-huan-neng-duo-yuan-kan-wan-miao/

多源BFS的實現思路:每一輪遍歷,從上一輪更新的節點向四周多走1步去更新節點,直到所有節點都被更新過一次。

時間複雜度是O(n*n*turn),只和所求的最長距離有關,和land數量無關。

實現代碼的參考:https://leetcode-cn.com/problems/as-far-from-land-as-possible/solution/lu-di-bu-duan-chang-da-zhi-dao-fu-gai-zheng-ge-di-/

class Solution {
public:
    int maxDistance(vector<vector<int>>& grid) {
        int n = grid.size();
        if(n==0) return -1;
        int land = 0, water, turn=0;
        for(int i=0; i<n; ++i){
            for(int j=0; j<n; ++j){
                if(grid[i][j]==1){
                    ++land;
                }
            }
        }
        if(land==0||land==n*n) {
            return -1;
        }
        water = n*n-land;
        while(water>0){
            ++turn;
            for(int i=0; i<n; ++i){
                for(int j=0; j<n; ++j){
                    if(grid[i][j]==turn){
                        if(i>0 && grid[i-1][j]==0){
                            grid[i-1][j] = turn+1;
                            --water;
                        }
                        if(i+1<n && grid[i+1][j]==0){
                            grid[i+1][j] = turn+1;
                            --water;
                        }
                        if(j>0 && grid[i][j-1]==0){
                            grid[i][j-1] = turn+1;
                            --water;
                        }
                        if(j+1<n && grid[i][j+1]==0){
                            grid[i][j+1] = turn+1;
                            --water;
                        }
                    }
                }
            }
        }
        return turn;
    }
};

 

法二:2個方向的dp

擴散要麼從左上方來,要麼從右下方來,因此從兩個方向做2次dp。

class Solution {
public:
    int maxDistance(vector<vector<int>>& grid) {
        int n = grid.size();
        if(n==0) return -1;
        int res = 0, land = 0;
        for(int i=0; i<n; ++i){
            for(int j=0; j<n; ++j){
                if(grid[i][j]!=1){
                    int tmp = INT_MAX-1;
                    if(i>0) tmp = min(tmp, grid[i-1][j]+1);
                    if(j>0) {
                        tmp = min(tmp, grid[i][j-1]+1);
                    }
                    grid[i][j] = tmp;
                }else{
                    ++land;
                }
            }
        }
        if( land==0 ||land==n*n) return -1;
        for(int i=n-1; i>=0; --i){
            for(int j=n-1; j>=0; --j){
                if(grid[i][j]!=1){
                    int tmp = grid[i][j];
                    if(i+1<n) tmp = min(tmp, grid[i+1][j]+1);
                    if(j+1<n) tmp = min(tmp, grid[i][j+1]+1);
                    grid[i][j] = tmp;
                    res = max(res, tmp);
                }
            }
        }
        return res-1;
    }
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章