LeetCode 1162. 地圖分析 (暴力循環+單源BFS、多源BFS、DP)

地圖分析

暴力循環+BFS

因爲要求每個0到1的最近距離,所以對於每個0進行BFS,搜到1時停止。然後挑出最大值即可。
這是最樸素的做法了。
循環 n^2次,每次(n ^2)
時間複雜度:O(n4)O(n^4)

const int dx[] = {-1,0,1,0};
const int dy[] = {0,1,0,-1};
class Solution {
public:
    int m,n;
    typedef pair<int,int> P;
    int maxDistance(vector<vector<int>>& grid) {
        m = grid.size();
        n = grid[0].size();
        int tot = 0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                tot += grid[i][j];
            }
        }
        if(tot==0 || tot ==m*n){
            return -1;
        }
        int mmax = 0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]){ continue; }
                int x = bfs(i,j,grid);
                // cout<<x<<"    "<<i<<":"<<j<<endl;
                mmax = max(x,mmax);
            }
        }
        return mmax;
    }

    int bfs(int i,int j,vector<vector<int>>& grid){
        queue<P> q;
        q.push(P(i,j));
        int dpt = 1;
        int vis[110][110] = {0};
        while(!q.empty()){
            int size =  q.size();
            while(size--){
                P p = q.front();
                q.pop();
                int x = p.first ,y = p.second;
                for(int k=0;k<4;k++){
                    int nx = x+dx[k];
                    int ny = y+dy[k]; 
                    if(nx>=0 && nx<m && ny>=0 && ny<n && !vis[nx][ny]  && grid[nx][ny]==0){
                        q.push(P(nx,ny));
                        vis[nx][ny] = 1;
                    }
                    if(nx>=0 && nx<m && ny>=0 && ny<n  && grid[nx][ny]==1){
                        return dpt;
                    }   
                }
            } 
            dpt++;
        }
        return 0;
    }

};

多個等價起始狀態的BFS

改變一下思路,將所有的1全部作爲起點加入隊列,然後去遍歷整張圖,最後一個被搜索到的0就是離所有1曼哈頓距離最大的。
圖片來自互聯網
在這裏插入圖片描述
時間複雜度: O(n2)O(n^2)

const int dx[] = {-1,0,1,0};
const int dy[] = {0,1,0,-1};
class Solution {
public:
    int maxDistance(vector<vector<int>>& grid) {
        typedef pair<int,int> P;
        queue<P> q;
        int m = grid.size(),n = grid[0].size();
        int d[110][110];
        memset(d,-1,sizeof(d));
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]){
                    q.push(P(i,j));
                    d[i][j] = 0;
                }
            }
        }
        if(q.size()==0 || q.size()==m*n){
            return -1;
        }
        int ans = 0;
        while(!q.empty()){
            int size = q.size();
            while(size--){
                P p = q.front();
                q.pop();
                int x = p.first;
                int y = p.second;
                for(int k=0;k<4;k++){
                    int nx = x+dx[k];
                    int ny = y+dy[k];
                    if(nx>=0 && nx<m && ny>=0 && ny<n
                       && d[nx][ny]==-1 ){
                           d[nx][ny] = d[x][y]+1;
                           q.push(P(nx,ny));
                           ans = max(ans,d[nx][ny]);
                    }
                }
            }
        }
        return ans;
    }
};

DP

DP題日後再刷

class Solution {
public:
    int maxDistance(vector<vector<int>>& grid) {
        int m = grid.size(), n = grid[0].size();
        //賦初值
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]==0){
                    grid[i][j] = 1e9;
                }else{
                    grid[i][j] = 0;
                }
            }
        }
        //從左上到右下
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(i-1>=0){
                    grid[i][j] = min(grid[i-1][j]+1,grid[i][j]);
                }
                if(j-1>=0){
                    grid[i][j] = min(grid[i][j-1]+1,grid[i][j]);
                }
            }
        }
        //從右下到左上
        for(int i=m-1;i>=0;i--){
            for(int j=n-1;j>=0;j--){
                if(i+1<m){
                    grid[i][j] = min(grid[i+1][j]+1,grid[i][j]);
                }
                if(j+1<n){
                    grid[i][j] = min(grid[i][j+1]+1,grid[i][j]);
                }
            }
        }
        //遍歷
        int ans = -1;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                ans = max(ans,grid[i][j]);
            }
        }
        if(ans==0 || ans==1e9){
            return -1;
        }
        return ans;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章