
 经典的dfs/bfs问题,给一个起点开始搜索,满足条件则继续调用dfs/bfs
从没有访问过的某个陆地出发,将所有能到达的陆地的状态都记录为已访问。下次出发不从已访问的陆地出发,每次出发前都把岛屿数 + 1即可
class Solution {
public:
    vector<vector<bool>> is_visited;
    const vector<pair<int, int>> direction = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
    int m_;
    int n_;
    bool is_valid(int x, int y){
        return x >= 0 && x < m_ && y >= 0 && y < n_;
    }
    void dfs(const vector<vector<char>>& grid, int i, int j) {
        is_visited[i][j] = true;
        for (auto d : direction) {
            int x = i + d.first;
            int y = j + d.second;
            if (is_valid(x, y) && !is_visited[x][y] && grid[x][y] == '1') {
                dfs(grid, x, y);
            }
        }
    }
    int numIslands(vector<vector<char>>& grid) {
        m_ = grid.size();
        n_ = grid[0].size();
        is_visited.resize(m_, vector<bool>(n_, false));
        int ans = 0;
        for(int i = 0; i < m_; i++){
            for(int j = 0; j < n_; j++){
                if(!is_visited[i][j] && grid[i][j] == '1'){
                    dfs(grid, i, j);
                    ans++;
                }
            }
        }
        return ans;
    }
};
遍历二维数组,合并不同的坐标时,在每个陆地坐标处查看自己右侧和下方的位置是否是陆地,如果是,合并当前陆地和自己右侧或下方的陆地
遍历完成后,并查集构造完成,直接获取并查集的集合数即可
class UnionFind{
    public:
        UnionFind(const vector<vector<char>>& grid){
            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] == '1') parent[i * n_ + j] = i * n_ + j;
                }
            }
        }
        int find_root(int x){
            // x不存在于并查集
            if(parent.find(x) == parent.end()) return -1;
            if(x == parent[x]) return x;
            parent[x] = find_root(parent[x]);
            return parent[x];
        }
        void merge(int x, int y){
            x = find_root(x);
            y = find_root(y);
            if(x != y) parent[x] = y;
        }
        int get_find_num() {
            unordered_set<int> st;
            // 遍历并查集,得到集合数量
            for (auto iter = parent.begin(); iter != parent.end(); iter++) {
                st.insert(find_root((*iter).first));
            }
            return st.size();
        }
    private:
        unordered_map<int, int> parent;  // 并查集
        int m_;
        int n_;
};
class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        UnionFind uf(grid);
        int m = grid.size();
        int n = grid[0].size();
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                // 如果自己右边或者下面是陆地,则合并集合
                if(grid[i][j] == '0') continue;
                if(i < m - 1){
                    // 可以查看下方
                    if(grid[i + 1][j] == '1') uf.merge(i * n + j, (i + 1) * n + j);
                }
                if(j < n - 1){
                    // 可以查看右边
                    if(grid[i][j + 1] == '1') uf.merge(i * n + j, i * n + (j + 1));
                }
            }
        }
        return uf.get_find_num();
    }
};



















