• 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);
        }
    };
  • 相关阅读:
    学习笔记-Bootstrap
    学习笔记-JavaScript
    学习笔记-HTML
    学习笔记-数据库操作
    学习笔记-MATLAB
    学习笔记-mysql基本操作
    学习笔记-Java进阶
    学习笔记-Java入门
    学习笔记-考研英语
    学习笔记-线代
  • 原文地址:https://www.cnblogs.com/joelwang/p/10875921.html
Copyright © 2020-2023  润新知