• 力扣(LeetCode)305. 岛屿数量 II(2022.11.02)


    给你一个大小为 m x n 的二进制网格 grid 。网格表示一个地图,其中,0 表示水,1 表示陆地。最初,grid 中的所有单元格都是水单元格(即,所有单元格都是 0)。

    可以通过执行 addLand 操作,将某个位置的水转换成陆地。给你一个数组 positions ,其中 positions[i] = [ri, ci] 是要执行第 i 次操作的位置 (ri, ci) 。

    返回一个整数数组 answer ,其中 answer[i] 是将单元格 (ri, ci) 转换为陆地后,地图中岛屿的数量。

    岛屿 的定义是被「水」包围的「陆地」,通过水平方向或者垂直方向上相邻的陆地连接而成。你可以假设地图网格的四边均被无边无际的「水」所包围。

    示例 1:
    在这里插入图片描述

    输入:m = 3, n = 3, positions = [[0,0],[0,1],[1,2],[2,1]]
    输出:[1,1,2,3]
    解释:
    起初,二维网格 grid 被全部注入「水」。(0 代表「水」,1 代表「陆地」)

    • 操作 #1:addLand(0, 0) 将 grid[0][0] 的水变为陆地。此时存在 1 个岛屿。
    • 操作 #2:addLand(0, 1) 将 grid[0][1] 的水变为陆地。此时存在 1 个岛屿。
    • 操作 #3:addLand(1, 2) 将 grid[1][2] 的水变为陆地。此时存在 2 个岛屿。
    • 操作 #4:addLand(2, 1) 将 grid[2][1] 的水变为陆地。此时存在 3 个岛屿。
      示例 2:

    输入:m = 1, n = 1, positions = [[0,0]]
    输出:[1]

    提示:

    1 <= m, n, positions.length <= 104
    1 <= m * n <= 104
    positions[i].length == 2
    0 <= ri < m
    0 <= ci < n

    进阶:你可以设计一个时间复杂度 O(k log(mn)) 的算法解决此问题吗?(其中 k == positions.length)

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/number-of-islands-ii

    方法一:并查集

    C++提交内容:

    #include 
    #include 
    
    using namespace std;
    
    class UnionFind {
    public:
        UnionFind(int N) {
            for (int i = 0; i < N; ++i) {
                parent.push_back(i);
            }
            count = 0;
        }
    
        bool isConnected(int x, int y) {
            return find(x) == find(y);
        }
    
        int getCount() {
            return count;
        }
    
        void addCount() {
            count++;
        }
    
        int find(int x) {
            if (parent[x] != x) {
                parent[x] = find(parent[x]);
            }
            return parent[x];
        }
    
        void unionSet(int x, int y) {
            int rootX = find(x);
            int rootY = find(y);
            if (rootX == rootY) {
                return;
            }
            
            parent[rootX] = rootY;
            count--;
        }
    
        int getCount() const {
            return count;
        }
    
    private:
        vector<int> parent;
        int count;
    };
    
    class Solution {
    private:
        bool inArea(int x, int y, int m, int n) {
            return x >= 0 && x < m && y >= 0 && y < n;
        }
    
    public:
        vector<int> numIslands2(int m, int n, vector<vector<int>> &positions) {
            UnionFind unionFind(m * n);
            vector<bool> visited;
            for (size_t i = 0; i < m * n; i++) {
                visited.push_back(false);
            }
    
            int DIRECTIONS[4][2] = {{0,  1},
                                    {1,  0},
                                    {0,  -1},
                                    {-1, 0}};
            vector<int> res;
            for (auto &position : positions) {
                int currX = position[0];
                int currY = position[1];
    
                int index = currX * n + currY;
                if (!visited[index]) {
                    // 把水变成陆地,连通分量个数加 1
                    unionFind.addCount();
                    visited[index] = true;
                    for (auto &direction : DIRECTIONS) {
                        int newX = currX + direction[0];
                        int newY = currY + direction[1];
                        int newIndex = newX * n + newY;
                        // 下面这三个条件很重要
                        if (inArea(newX, newY, m, n)
                            && visited[newIndex]
                            && !unionFind.isConnected(index, newIndex)) {
                            unionFind.unionSet(index, newIndex);
                        }
                    }
                }
                res.push_back(unionFind.getCount());
            }
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
  • 相关阅读:
    Vue2 测试解决方案
    人工智能算法面试大总结-总目录
    代码随想录 | Day59
    【PCBA方案】电子握力测试仪方案she‘ji
    LeetCode20.有效的括号
    拥抱 AGI:PieDataCS 引领云原生数据计算系统新范式
    云原生之快速使用Nacos Spring Cloud
    Windows11+Ubuntu 3系统如何安全地删掉最后一个Ubuntu系统?
    Mybatis框架的搭建和基本使用
    Nginx 配置 HTTPS 过程(+反向代理)
  • 原文地址:https://blog.csdn.net/ChaoYue_miku/article/details/127661162