[LeetCode] Number of Islands II 岛屿的数量之二

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.

Example:

Given m = 3, n = 3positions = [[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]

Challenge:

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

这道题是之前那道Number of Islands的拓展,难度增加了不少,因为这次是一个点一个点的增加,每增加一个点,都要统一一下现在总共的岛屿个数,最开始初始化时没有陆地,如下:

0 0 0
0 0 0
0 0 0

假如我们在(0, 0)的位置增加一个陆地,那么此时岛屿数量为1:

1 0 0
0 0 0
0 0 0

假如我们再在(0, 2)的位置增加一个陆地,那么此时岛屿数量为2:

1 0 1
0 0 0
0 0 0

假如我们再在(0, 1)的位置增加一个陆地,那么此时岛屿数量却又变为1:

1 1 1
0 0 0
0 0 0

假如我们再在(1, 1)的位置增加一个陆地,那么此时岛屿数量仍为1:

1 1 1
0 1 0
0 0 0

那么我们为了解决这种陆地之间会合并的情况,最好能够将每个陆地都标记出其属于哪个岛屿,这样就会方便我们统计岛屿个数,于是我们需要一个长度为m*n的一维数组来标记各个位置属于哪个岛屿,我们假设每个位置都是一个单独岛屿,岛屿编号可以用其坐标位置表示,但是我们初始化时将其都赋为-1,这样方便我们知道哪些位置尚未开发。然后我们开始遍历陆地数组,将其岛屿编号设置为其坐标位置,然后岛屿计数加1,我们此时开始遍历其上下左右的位置,遇到越界或者岛屿标号为-1的情况直接跳过,否则我们来查找邻居位置的岛屿编号,如果邻居的岛屿编号和当前点的编号不同,说明我们需要合并岛屿,将此点的编号赋为邻居的编号,在编号数组里也要修改,并将岛屿计数cnt减1。当我们遍历完当前点的所有邻居时,该合并的都合并完了,将此时的岛屿计数cnt存入结果中。

注意在查找岛屿编号的函数中我们可以做路径压缩Path Compression,只需加上一行roots[id] = roots[roots[id]];这样在编号数组中,所有属于同一个岛屿的点的编号都相同,可以自行用上面的那个例子来一步一步的走看roots的值的变化过程:

roots:

-1 -1 -1 -1 -1 -1 -1 -1 -1
 0 -1 -1 -1 -1 -1 -1 -1 -1
 0 -1  2 -1 -1 -1 -1 -1 -1
 2  0  2 -1 -1 -1 -1 -1 -1
 2  2  2 -1  2 -1 -1 -1 -1

class Solution {
public:
    vector<int> numIslands2(int m, int n, vector<pair<int, int>>& positions) {
        vector<int> res;
        if (m <= 0 || n <= 0) return res;
        vector<int> roots(m * n, -1);
        int cnt = 0;
        vector<vector<int> > dirs{{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
        for (auto a : positions) {
            int id = n * a.first + a.second;
            roots[id] = id;
            ++cnt;
            for (auto d : dirs) {
                int x = a.first + d[0], y = a.second + d[1];
                int cur_id = n * x + y;
                if (x < 0 || x >= m || y < 0 || y >= n || roots[cur_id] == -1) continue;
                int new_id = findRoots(roots, cur_id);
                if (id != new_id) {
                    roots[id] = new_id;
                    id = new_id;
                    --cnt;
                }
            }
            res.push_back(cnt);
        }
        return res;
    }
    int findRoots(vector<int> &roots, int id) {
        while (id != roots[id]) {
            roots[id] = roots[roots[id]];
            id = roots[id];
        }
        return id;
    }
};

类似题目:

Number of Islands

参考资料:

https://leetcode.com/discuss/69572/easiest-java-solution-with-explanations

LeetCode All in One 题目讲解汇总(持续更新中...)

时间: 2024-10-05 02:45:14

[LeetCode] Number of Islands II 岛屿的数量之二的相关文章

[LeetCode] Number of Islands II

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

第九篇 LeetCode Number of Islands II

UnifonFind with path compression and weighting O(klogmn), k is the length of positions array public class Solution { public List<Integer> numIslands2(int m, int n, int[][] positions) { List<Integer> result = new ArrayList<Integer>(); if

第八篇 LeetCode Number of Islands

好久没更新了,终于考完了继续回来刷题 岛屿问题属于最基本的DFS, BFS题目 使用DFS时会遇到如果图太大call stack过深的follow up,此时可以转为使用BFS 下一篇Number of Islands II 中将使用另一种Union Find的做法 public class Solution { public int numIslands(char[][] grid) { if (grid == null || grid.length == 0) { return 0; } i

305.Number of Islands II

/* * 305.Number of Islands II * 2016-4-3 by Mingyang *Union Find 的题目,直接略过 */ private int[][] dir = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}}; public List<Integer> numIslands2(int m, int n, int[][] positions) { UnionFind2D islands = new UnionFind2D(m, n); L

Leetcode 305. Number of Islands II

Problem: 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

Number of Islands II

Given a n,m which means the row and column of the 2D matrix and an array of pair A( size k). Originally, the 2D matrix is all 0 which means there is only sea in the matrix. The list pair has k operator and each operator has two integer A[i].x, A[i].y

[LeetCode] Number of Islands

Number of Islands 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

LeetCode Number of Islands 岛的数量(DFS,BFS)

题意:0代表水,1代表陆地,那么被水围起来的就是岛了,给一个01矩阵,问有多少个岛? 思路:DFS还是比较短,实现了一下.如果一个点已经被遍历过了,那就将其置为0就行了,不要去搜0的. 1 class Solution { 2 public: 3 bool isok(vector<vector<char> >& grid,int x,int y) 4 { 5 return x>=0 && y>=0 && x<grid.siz

LintCode &quot;Number of Islands II&quot;

A typical Union-Find one. I'm using a kinda Union-Find solution here. Some boiler-plate code - yeah I know. class Solution { unordered_set<int> hs; // start from 1 int max_k; public: void dfs(vector<vector<int>> &mt, int x, int y, in