You are given an empty 2D binary grid grid
of size m x n
. The grid represents a map where 0
's represent water and 1
's represent land. Initially, all the cells of grid
are water cells (i.e., all the cells are 0
's).
We may perform an add land operation which turns the water at position into a land. You are given an array positions
where positions[i] = [ri, ci]
is the position (ri, ci)
at which we should operate the ith
operation.
Return an array of integers answer
where answer[i]
is the number of islands after turning the cell (ri, ci)
into a land.
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:
Input: m = 3, n = 3, positions = [[0,0],[0,1],[1,2],[2,1]] Output: [1,1,2,3] Explanation: Initially, the 2d grid is filled with water. - Operation #1: addLand(0, 0) turns the water at grid[0][0] into a land. We have 1 island. - Operation #2: addLand(0, 1) turns the water at grid[0][1] into a land. We still have 1 island. - Operation #3: addLand(1, 2) turns the water at grid[1][2] into a land. We have 2 islands. - Operation #4: addLand(2, 1) turns the water at grid[2][1] into a land. We have 3 islands.
Example 2:
Input: m = 1, n = 1, positions = [[0,0]] Output: [1]
Constraints:
1 <= m, n, positions.length <= 104
1 <= m * n <= 104
positions[i].length == 2
0 <= ri < m
0 <= ci < n
Follow up: Could you solve it in time complexity O(k log(mn))
, where k == positions.length
?
Union find.
class Solution:
def numIslands2(self, m: int, n: int, positions: List[List[int]]) -> List[int]:
p = list(range(m * n))
grid = [[0] * n for _ in range(m)]
def check(i, j):
return 0 <= i < m and 0 <= j < n and grid[i][j] == 1
def find(x):
if p[x] != x:
p[x] = find(p[x])
return p[x]
res = []
cur = 0
for i, j in positions:
if grid[i][j] == 1:
res.append(cur)
continue
grid[i][j] = 1
cur += 1
for x, y in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
if check(i + x, j + y) and find(i * n + j) != find((i + x) * n + j + y):
p[find(i * n + j)] = find((i + x) * n + j + y)
cur -= 1
res.append(cur)
return res
class Solution {
private int[] p;
private int[][] dirs = new int[][]{{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
private int[][] grid;
private int m;
private int n;
public List<Integer> numIslands2(int m, int n, int[][] positions) {
p = new int[m * n];
for (int i = 0; i < p.length; ++i) {
p[i] = i;
}
grid = new int[m][n];
this.m = m;
this.n = n;
List<Integer> res = new ArrayList<>();
int cur = 0;
for (int[] position : positions) {
int i = position[0], j = position[1];
if (grid[i][j] == 1) {
res.add(cur);
continue;
}
grid[i][j] = 1;
++cur;
for (int[] e : dirs) {
if (check(i + e[0], j + e[1]) && find(i * n + j) != find((i + e[0]) * n + j + e[1])) {
p[find(i * n + j)] = find((i + e[0]) * n + j + e[1]);
--cur;
}
}
res.add(cur);
}
return res;
}
private boolean check(int i, int j) {
return i >= 0 && i < m && j >= 0 && j < n && grid[i][j] == 1;
}
private int find(int x) {
if (p[x] != x) {
p[x] = find(p[x]);
}
return p[x];
}
}
class Solution {
public:
vector<int> p;
int dirs[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
vector<int> numIslands2(int m, int n, vector<vector<int>>& positions) {
p.resize(m * n);
for (int i = 0; i < p.size(); ++i) p[i] = i;
vector<vector<int>> grid(m, vector<int>(n, 0));
vector<int> res;
int cur = 0;
for (auto position : positions)
{
int i = position[0], j = position[1];
if (grid[i][j] == 1)
{
res.push_back(cur);
continue;
}
grid[i][j] = 1;
++cur;
for (auto e : dirs) {
if (check(i + e[0], j + e[1], grid) && find(i * n + j) != find((i + e[0]) * n + j + e[1]))
{
p[find(i * n + j)] = find((i + e[0]) * n + j + e[1]);
--cur;
}
}
res.push_back(cur);
}
return res;
}
bool check(int i, int j, vector<vector<int>>& grid) {
return i >= 0 && i < grid.size() && j >= 0 && j < grid[0].size() && grid[i][j] == 1;
}
int find(int x) {
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
};
var p []int
func numIslands2(m int, n int, positions [][]int) []int {
p = make([]int, m*n)
for i := 0; i < len(p); i++ {
p[i] = i
}
grid := make([][]int, m)
for i := 0; i < m; i++ {
grid[i] = make([]int, n)
}
var res []int
cur := 0
dirs := [4][2]int{{0, -1}, {0, 1}, {1, 0}, {-1, 0}}
for _, position := range positions {
i, j := position[0], position[1]
if grid[i][j] == 1 {
res = append(res, cur)
continue
}
grid[i][j] = 1
cur++
for _, e := range dirs {
if check(i+e[0], j+e[1], grid) && find(i*n+j) != find((i+e[0])*n+j+e[1]) {
p[find(i*n+j)] = find((i+e[0])*n + j + e[1])
cur--
}
}
res = append(res, cur)
}
return res
}
func check(i, j int, grid [][]int) bool {
return i >= 0 && i < len(grid) && j >= 0 && j < len(grid[0]) && grid[i][j] == 1
}
func find(x int) int {
if p[x] != x {
p[x] = find(p[x])
}
return p[x]
}