-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLC0454.py
89 lines (79 loc) · 3.65 KB
/
LC0454.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class Solution:
# Directions in which we can traverse inside the grids.
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
# Helper method to check if the cell at the position (x, y) in the 'grid'
# is a land cell.
def is_cell_land(self, x, y, grid):
return grid[x][y] == 1
# Union-Find class.
class UnionFind:
def __init__(self, n):
self.parent = list(range(n))
self.rank = [0] * n
# Find the root of element 'u', using the path-compression technique.
def find(self, u):
if self.parent[u] != u:
self.parent[u] = self.find(self.parent[u])
return self.parent[u]
# Union two components of elements 'u' and 'v' respectively based on their ranks.
def union_sets(self, u, v):
root_u = self.find(u)
root_v = self.find(v)
if root_u != root_v:
if self.rank[root_u] > self.rank[root_v]:
self.parent[root_v] = root_u
elif self.rank[root_u] < self.rank[root_v]:
self.parent[root_u] = root_v
else:
self.parent[root_v] = root_u
self.rank[root_u] += 1
# Helper method to convert (x, y) position to a 1-dimensional index.
def convert_to_index(self, x, y, total_cols):
return x * total_cols + y
def countSubIslands(
self, grid1: List[List[int]], grid2: List[List[int]]
) -> int:
total_rows = len(grid2)
total_cols = len(grid2[0])
uf = self.UnionFind(total_rows * total_cols)
# Traverse each land cell of 'grid2'.
for x in range(total_rows):
for y in range(total_cols):
if self.is_cell_land(x, y, grid2):
# Union adjacent land cells with the current land cell.
for direction in self.directions:
next_x = x + direction[0]
next_y = y + direction[1]
if (
0 <= next_x < total_rows
and 0 <= next_y < total_cols
and self.is_cell_land(next_x, next_y, grid2)
):
uf.union_sets(
self.convert_to_index(x, y, total_cols),
self.convert_to_index(
next_x, next_y, total_cols
),
)
# Traverse 'grid2' land cells and mark that cell's root as not a sub-island
# if the land cell is not present at the respective position in 'grid1'.
is_sub_island = [True] * (total_rows * total_cols)
for x in range(total_rows):
for y in range(total_cols):
if self.is_cell_land(x, y, grid2) and not self.is_cell_land(
x, y, grid1
):
root = uf.find(self.convert_to_index(x, y, total_cols))
is_sub_island[root] = False
# Count all the sub-islands.
sub_island_counts = 0
for x in range(total_rows):
for y in range(total_cols):
if self.is_cell_land(x, y, grid2):
root = uf.find(self.convert_to_index(x, y, total_cols))
if is_sub_island[root]:
sub_island_counts += 1
# One cell can be the root of multiple land cells, so to
# avoid counting the same island multiple times, mark it as false.
is_sub_island[root] = False
return sub_island_counts