The power of this "island problem" is demonstrated by using the combination and checking!

For the previous island problem, it is easier and more efficient to use DFS and BFS than to use union search, but for this question, 827. The largest artificial island , it is easier to use union search.
[Title] You are given a n x nbinary matrix of size grid. Only one grid of 0 can be changed to 1 at most. After doing this, gridwhat is the largest island area in ? 岛屿It is formed by a group of 1s connected in four directions: up, down, left, and right.

The requirement of the question is to change a grid of 0 into 1 and then see how much the largest island can be. Therefore, you can use the up, down, left, and right to judge the size of the island and the current 0 combination to record the largest island. The idea is as follows:

  • The first traversal grid: record all the islands, and rankget the area of ​​the islands through ;
  • The second traversal grid: When encountering a position of 0, record the area of ​​the islands connected by the area of ​​the upper, lower, left, and right islands after changing the current position to 1. The specific method:
    • Use a variable area = 1to record the area;
    • Determine whether the top, bottom, left, and right positions are 1, and if it is 1, get the area of ​​the island and add it to area;
    • Also remember to add an extra variable seento record whether the island has been seen. Because it is possible that there are up, down, left, and right islands that belong to the same island;

First implement the union search set:

class UnionFind {
    
    
public:
    int count;
    vector<int> parent;
    vector<int> rank;

    UnionFind(int n) {
    
    
        count = n;
        parent = vector<int>(n);
        rank = vector<int>(n, 1);
        for (int i = 0; i < parent.size(); i++) {
    
    
            parent[i] = i;
        }
    }

    int Find(int x) {
    
    
        if (parent[x] != x) {
    
    
            parent[x] = Find(parent[x]);
        }
        return parent[x];
    }

    void Union(int x, int y) {
    
    
        int root_x = Find(x), root_y = Find(y);
        if (root_x == root_y) {
    
     return; }
        if (rank[root_x] >= rank[root_y]) {
    
    
            parent[root_y] = root_x;
            rank[root_x] += rank[root_y];
        } else {
    
    
            parent[root_x] = root_y;
            rank[root_y] += rank[root_x];
        }
    }
};

Then the main logic of the topic:

class Solution {
    
    
public:
    int largestIsland(vector<vector<int>>& grid) {
    
    
        // 遍历整个 grid 创建并查集
        int n = grid.size();
        UnionFind uf(n * n);
        int dx[4] = {
    
    -1, 1, 0, 0};
        int dy[4] = {
    
    0, 0, -1, 1};
        for (int i = 0; i < n; i++) {
    
    
            for (int j = 0; j < n; j++) {
    
    
                if (grid[i][j] == 1) {
    
    
                    for (int k = 0; k < 4; k++) {
    
    
                        int nx = i + dx[k];
                        int ny = j + dy[k];
                        if (nx >= 0 && nx < n && ny >= 0 && ny < n && grid[nx][ny] == 1) {
    
    
                            uf.Union(i * n + j, nx * n + ny);
                        }
                    }
                }
            }
        }

        int maxArea = 0;
        // 遍历所有的 0, 并且判断如果将这个 0 变为 1 之后的最大面积是多少
        for (int i = 0; i < n; i++) {
    
    
            for (int j = 0; j < n; j++) {
    
    
                if (grid[i][j] == 1) {
    
     // 直接比较当前的面积大小
                    maxArea = max(maxArea, uf.rank[uf.Find(i * n + j)]);
                } else if (grid[i][j] == 0) {
    
    
                    int area = 1;  // 当前位置变为 1
                    set<int> seen;
                    for (int k = 0; k < 4; k++) {
    
    
                        int nx = i + dx[k];
                        int ny = j + dy[k];
                        if (nx >= 0 && nx < n && ny >= 0 && ny < n && grid[nx][ny] == 1) {
    
    
                            int root_x = uf.Find(nx * n + ny);
                            if (seen.count(root_x) == 0) {
    
    
                                area += uf.rank[root_x];
                                seen.insert(root_x);
                            }
                        }
                    }
                    maxArea = max(maxArea, area);
                }
            }
        }
        return maxArea;
    }
};

The solution to the problem on LeetCode is: The power of union search is finally brought into play! [C++ and check set]

Guess you like

Origin blog.csdn.net/weixin_39679367/article/details/128486802