leetcode 200. 岛屿数量

200. 岛屿数量
难度:中
题目概述:找到属于同一个区域的点,典型的并查集问题。。
题解1:DFS
这道题不能采用修改原数组的值做访问标记,所以需要增加一个遍历标记数组。
有些题目,原数组的值会在遍历过程中被修改,所以通常可以直接用原数组的值做标记,进而节省内存。

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        if (grid.empty() || grid[0].empty()) return 0;
        vector<vector<bool>> visited(m, vector<bool>(n));
        for (int i = 0; i < grid.size(); ++i) {
            for (int j = 0; j < grid[0].size(); ++j) {
                if (grid[i][j] == '0' || visited[i][j]) continue;
                dfs(grid, visited, i, j);
                ++res;
            }
        }
        return res;
    }
    void dfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) {
        if (x < 0 || x >= grid.size() || y < 0 || y >= grid[0].size() || grid[x][y] == '0' || visited[x][y]) return;
        visited[x][y] = true;
        dfs(grid, visited, x - 1, y);
        dfs(grid, visited, x + 1, y);
        dfs(grid, visited, x, y - 1);
        dfs(grid, visited, x, y + 1);
    }
};

就dfs而言依然是一道模板题。
题解2:BFS
对于坐标的处理,可以不采用pair<int,int>的方式,因为pair标记坐标的处理开销要大于int。
通常可以将二维数组转化为一维数组进行处理,用行*列+列的方式标记。

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
        if (grid.empty() || grid[0].empty()) return 0;
        int m = grid.size(), n = grid[0].size(), res = 0;
        vector<vector<int>> visited(m, vector<int>(n));
        vector<int> dirx{-1, 0, 1, 0}, diry{0, 1, 0, -1};
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (grid[i][j] == '0' || visited[i][j]) continue;
                ++res;
                queue<int> q{{i * n + j}};
                while (!q.empty()) {
                    int t = q.front(); q.pop();
                    for (int k = 0; k < 4; ++k) {
                        int x = t / n + dirx[k], y = t % n + diry[k];
                        if (x < 0 || x >= m || y < 0 || y >= n || grid[x][y] == '0' || visited[x][y] == 1) continue;
                        visited[x][y] = 1;
                        q.push(x * n + y);
                    }
                }
            }
        }
        return res;
    }
};

题解3:并查集
并查集三步法
1.建立根,初始化,每个节点为独立孤岛;建立find和uion函数。上述都是模板
2.根据表的结构关系,建立集合关系。(可能在完成这一步后,题目已经求解)
3.根据题目的具体要求,处理集合关系。

class Solution {
public:
    vector<int> root_group;
    int count=0;
    int numIslands(vector<vector<char>>& grid) {
        if (grid.size() == 0 || grid[0].size() == 0) return 0;
        int length = grid.size() * grid[0].size();
        int width = grid[0].size();
        root_group = vector<int>(length, 0);
        for(int i = 0; i < length; i++) {
            int x = i / width, y = i % width;
            if (grid[x][y] == '1') count++;
            root_group[i] = i;
        }
        for(int j = 0; j < length; j++){
            int x = j / width, y = j % width;
            int down = x + 1, right = y + 1;
            if (down < grid.size() && grid[x][y] == '1' && grid[down][y] == '1')
             unin(j, j+width);
            if ( right < grid[0].size() && grid[x][y] == '1' && grid[x][right] == '1')
             unin(j, j+1);
        }
        return count;
    }

    void unin(int x,int y){
        int rootx = find(x);
        int rooty = find(y);
        if (rootx == rooty)return;
        root_group[rootx] = rooty;
        count--;
    }

    int find(int p){
        while (p != root_group[p]) {
            root_group[p] = root_group[root_group[p]];
            p = root_group[p];
        }
        return p;
    }
};
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容