200. Number of Islands (Medium)

Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. 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.

Example 1:

11110
11010
11000
00000

Answer: 1

Example 2:

11000
11000
00100
00011

Answer: 3

Time complexity: $$O(ROW x COL)$$

union-find

class Solution {

private:

    vector<int> id,sz;

    int root(int i) {
        // path compression
        while (i != id[i]) {
            id[i] = id[id[i]];
            i = id[i];
        }
        return i;
    }

    bool connected(int p, int q) {
        return root(p) == root(q);
    }

    void unionT(int p, int q) {
        // weighted
        int i = root(p);
        int j = root(q);
        if (i == j) return;
        if (sz[i] < sz[j]) { id[i] = j; sz[j] += sz[i];}
        else { id[j] = i; sz[i] += sz[j]; }
    }



public:
    int numIslands(vector<vector<char>>& grid) {

        int n = grid.size();
        if (n==0) return 0;
        int m = grid[0].size();
        int num = grid[0][0]-'0';

        int size = n*m;

        id.resize(size);
        sz.resize(size);

        for (int i = 0; i < size; ++i) {
            id[i] = i;
            sz[i] = 1;
        }

        for (int j = 1; j < m; ++j) {
            if (grid[0][j] == '1') {
                if (grid[0][j-1] == '1') {
                   unionT(j-1, j);
                } else {
                    ++num;
                }
            }
        }

        for (int i = 1; i < n; ++i) {
            if (grid[i][0] == '1') {
                if (grid[i-1][0] == '1') {
                    unionT((i-1)*m, i*m);
                } else {
                    ++num;
                }
            }
        }

        for (int i = 1; i < n; ++i) {
            for (int j = 1; j < m; ++j) {
                if (grid[i][j] == '1') {
                    int idx = i*m+j;

                    if (grid[i-1][j] == '1' && grid[i][j-1] == '1') {
                        int root1 = root(idx-m);
                        int root2 = root(idx-1);
                        if (root1 != root2) {
                            --num;

                            //unionT(idx-1, idx-m);
                            if (sz[root1] < sz[root2]) { id[root1] = root2; sz[root2] += sz[root1]; root1 = root2;}
                            else { id[root2] = root1; sz[root1] += sz[root2]; }


                            // unionT(idx-m, idx);
                            root2 = root(idx);
                            if (sz[root1] < sz[root2]) { id[root1] = root2; sz[root2] += sz[root1];}
                            else { id[root2] = root1; sz[root1] += sz[root2]; }
                        } else {
                            unionT(idx-m, idx);
                        }
                    } else if (grid[i-1][j] == '1') {
                        unionT(idx-m, idx);
                    } else if (grid[i][j-1] == '1') {
                        unionT(idx-1, idx);
                    } else {
                        ++num;
                    }

                }

            }
        }

        return num;

    }
};

dfs

  • recursive
void dfs(vector<vector<char>>& grid, int x, int y) {
    if (x < 0 || x >= grid.size()) return;
    if (y < 0 || y >= grid[0].size()) return;

    if (grid[x][y] == '0') return;
    grid[x][y] = '0';
    dfs(grid, x+1, y);
    dfs(grid, x-1, y);
    dfs(grid, x, y+1);
    dfs(grid, x, y-1);

}

int numIslands(vector<vector<char>>& grid) {
    if (grid.size() == 0 || grid[0].size() == 0) return 0;
    int n = grid.size(), m = grid[0].size();
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (grid[i][j] == '1') {
                dfs(grid, i, j);
                ++cnt;
            }
        }
    }
    return cnt;
}
  • iterative
void dfs(vector<vector<char>>& grid, int x, int y) {
    static int r[] = {1, -1, 0, 0};
    static int c[] = {0, 0, 1, -1};

    stack<pair<int,int> > s;
    s.push({x,y});
    grid[x][y] = '0';

    while (!s.empty()) {
        int x = s.top().first;
        int y = s.top().second;
        s.pop();

        for (int i = 0; i < 4; ++i) {
            int nx = x+r[i], ny = y+c[i];
            // cheack within bound
            if (nx>=0 && nx<grid.size() && ny>=0 && ny<grid[0].size() && grid[nx][ny]=='1') {
                s.push({nx, ny});
                grid[nx][ny] = '0';
            }
        }
    }
}

bfs

  • recursive

bfs cannot be implemented by using recursion. You need use queue. dfs is the one which uses recursion to implement.

  • iterative
void bfs(vector<vector<char>>& grid, int x, int y) {

    static int r[] = {1, -1, 0, 0};
    static int c[] = {0, 0, 1, -1};

    queue<pair<int,int> > s;
    s.push({x,y});
    grid[x][y] = '0';

    while (!s.empty()) {
        int x = s.front().first;
        int y = s.front().second;
        s.pop();

        for (int i = 0; i < 4; ++i) {
            int nx = x+r[i], ny = y+c[i];
            if (nx>=0 && nx<grid.size() && ny>=0 && ny<grid[0].size() && grid[nx][ny]=='1') {
                s.push({nx, ny});
                grid[nx][ny] = '0';
            }
        }
    }
}

int numIslands(vector<vector<char>>& grid) {
    if (grid.size() == 0 || grid[0].size() == 0) return 0;
    int n = grid.size(), m = grid[0].size();
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (grid[i][j] == '1') {
                bfs(grid, i, j);
                ++cnt;
            }
        }
    }
    return cnt;
}

results matching ""

    No results matching ""