美文网首页
18. Number of Islands II

18. Number of Islands II

作者: 邓博文_7c0a | 来源:发表于2018-01-26 05:48 被阅读0次

Link to the problem

Description

A 2d grid map of m rows and n columns is initially filled with water. We may perform an addLand operation which turns the water at position (row, col) into a land. Given a list of positions to operate, count the number of islands after each addLand operation. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Can you do it in time complexity O(k log mn), where k is the length of the positions?

Example

Given m = 3, n = 3, positions = [[0,0], [0,1], [1,2], [2,1]].
Initially, the 2d grid grid is filled with water. (Assume 0 represents water and 1 represents land).

0 0 0
0 0 0
0 0 0
Operation #1: addLand(0, 0) turns the water at grid[0][0] into a land.

1 0 0
0 0 0 Number of islands = 1
0 0 0
Operation #2: addLand(0, 1) turns the water at grid[0][1] into a land.

1 1 0
0 0 0 Number of islands = 1
0 0 0
Operation #3: addLand(1, 2) turns the water at grid[1][2] into a land.

1 1 0
0 0 1 Number of islands = 2
0 0 0
Operation #4: addLand(2, 1) turns the water at grid[2][1] into a land.

1 1 0
0 0 1 Number of islands = 3
0 1 0
We return the result as an array: [1, 1, 2, 3]

Idea

Use a union find data structure. Each time a one is inserted, make it its own parent, and add edges to its neighboring ones.

Solution

class UnionFind {
public:
    UnionFind(int m, int n) {
        count = 0, capacity = 0;
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                parent.push_back(-1);
                rank.push_back(0);
                capacity++;
            }
        }
    }
    
    int getParent(int node) {
        if (parent[node] != node) {
            parent[node] = getParent(parent[node]);
        }
        return parent[node];
    }
    
    bool contains(int node) {
        return (node >= 0) && (node < capacity) && parent[node] >= 0;
    }
    
    bool setParent(int node) {
        if (parent[node] < 0) {
            parent[node] = node;
            rank[node] = 1;
            count++;
            return true;
        }
        return false;
    }
    
    void join(int node1, int node2) {
        int group1 = getParent(node1);
        int group2 = getParent(node2);
        if (group1 != group2) {
            count--;
            // Join two groups
            int rank1 = rank[group1], rank2 = rank[group2];
            if (rank1 < rank2) {
                parent[group1] = group2;
            } else if (rank1 > rank2) {
                parent[group2] = group1;
            } else {
                parent[group1] = group2;
                rank[group2]++;
            }
        }
    }
    
    int getCount() {
        return count;
    }
    
private:
    int count;
    int capacity;
    vector<int> parent;
    vector<int> rank;
};

class Solution {
public:
    vector<int> numIslands2(int m, int n, vector<pair<int, int>> &positions) {
        UnionFind uf(m, n);
        vector<int> rtn;
        for (auto pos = positions.begin(); pos != positions.end(); ++pos) {
            int node = pos->first * n + pos->second;
            if (uf.setParent(node)) {
                if (node % n && uf.contains(node - 1)) uf.join(node, node - 1);
                if (uf.contains(node - n)) uf.join(node, node - n);
                if ((node + 1) % n && uf.contains(node + 1)) uf.join(node, node + 1);
                if (uf.contains(node + n)) uf.join(node, node + n);                
            }
            rtn.push_back(uf.getCount());
        }
        return rtn;
    }
};

158 / 158 test cases passed.
Runtime: 100 ms

相关文章

网友评论

      本文标题:18. Number of Islands II

      本文链接:https://www.haomeiwen.com/subject/knumaxtx.html