# LeetCode 305：岛屿数量2

### 题目

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:

Input: m = 3, n = 3, positions = [[0,0], [0,1], [1,2], [2,1]]
Output: [1,1,2,3]
Explanation:

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 grid0 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 grid0 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 grid1 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 grid2 into a land.

1 1 0
0 0 1   Number of islands = 3
0 1 0

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

### 解答

class Solution {
public:
vector<int> numIslands2(int m, int n, vector<vector<int>>& positions) {
vector<int> res;
int cnt = 0;    // 岛屿数量
vector<int> father(m * n, -1);    // 开始全是水，初始化为-1
vector<vector<int>> directions{{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
for (auto &pos : positions) {
int id = n * pos[0] + pos[1];
if (father[id] != -1) {    // 重复出现的位置，无需重新计算，直接将cnt加入结果
res.push_back(cnt);
continue;
}
father[id] = id;    // 初始化：每块陆地的父节点(所属岛屿)为自己
++cnt;
for (auto direction: directions) {
int x = pos[0] + direction[0], y = pos[1] + direction[1];
int cur_id = n * x + y;
if (x < 0 || x >= m || y < 0 || y >= n || father[cur_id] == -1) // 越界或该位置是水，直接跳过
continue;

// Union操作
int p = find(father, cur_id), q = find(father, id);
if (p != q) {
father[p] = q;
--cnt;
}
}
res.push_back(cnt);
}
return res;
}

int find(vector<int>& father, int id) {
if (father[id] != id) {
father[id] = find(father, father[id]);    // 路径压缩
}
return father[id];
}
};

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客