18. Number of Islands II

2018-01-26  本文已影响0人  邓博文_7c0a

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

上一篇 下一篇

猜你喜欢

热点阅读