leetcode 200岛屿的个数

 

 

主要考察图搜索:

方法一:染色法,时间O(mn)

遍历一遍,再通过BFS或DFS将所有临近岛屿染色,使用dfs时将numIslands中的bfs换成dfs即可;

/*****
遍历所有的点:
    只要遇见陆地(1),投放1枚原子弹,爆炸冲击波以BFS或DFS的形式向外扩散,使得自身及所有相邻区域全部夷为平地;
最终遍历结束,原子弹使用数目即为岛屿次数
*****/

class Solution {
public:
    vector<vector<int> > dirs={{-1,0},{0,1},{1,0},{0,-1}};
    int numIslands(vector<vector<char>>& grid) {
        int m=grid.size();
        if(m==0) return 0;
        int n=grid[0].size();
        if(n==0) return 0;
        int res=0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]=='1'){
                    res++;bfs(grid,i,j);
                }
            }
        }
        return res;
    }
    void dfs(vector<vector<char>>&grid,int i,int j){
        int m=grid.size(),n=grid[0].size();
        if(i<0 || i>=m ||j<0 ||j>=n||grid[i][j]!='1') return;
        grid[i][j]='0';
        for(auto dir:dirs){
            dfs(grid,i+dir[0],j+dir[1]);
        }
    }
    void bfs(vector<vector<char>>&grid,int i,int j){
        int m=grid.size(),n=grid[0].size();
        queue<pair<int,int>> q;
        pair<int,int> p;
        p.first=i,p.second=j;
        q.push(p);
        while(!q.empty()){
            p=q.front();
            q.pop();
            int a=p.first,b=p.second;
            if(a>=0 && a<m && b>=0 && b<n && grid[a][b]=='1'){
                grid[a][b]='0';
                for(auto dir:dirs){
                    pair<int,int> tmp;
                    tmp.first=a+dir[0],tmp.second=b+dir[1];
                    q.push(tmp);
                }
            }
        }
    }
};

第二种:并查集的方法,

 

class Solution {
public:
    int findCircleNum(vector<vector<int>>& M) {
        if (M.empty()) return 0;
        int n = M.size();

        vector<int> leads(n, 0);
        for (int i = 0; i < n; i++) { leads[i] = i; }   // initialize leads for every kid as themselves

        int groups = n;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {   // avoid recalculate M[i][j], M[j][i]
                if (M[i][j]) {
                    int lead1 = find(i, leads);
                    int lead2 = find(j, leads);
                    if (lead1 != lead2) {       // if 2 group belongs 2 different leads, merge 2 group to 1
                        leads[lead1] = lead2;
                        groups--;
                    }
                }
            }
        }
        return groups;
    }

private:
    int find(int x, vector<int>& parents) {
        return parents[x] == x ? x : find(parents[x], parents);
    }
};

 

posted @ 2019-05-16 15:33  Joel_Wang  阅读(464)  评论(0编辑  收藏  举报