In [19]:
1
2
3
4
5
6
7
import sys, random
sys.path.append("/home/swyoo/algorithm/")
from utils.verbose import visualize_graph, visualize_ds, logging_time
from typing import List
from collections import deque
from pprint import pprint
import numpy as np
200. Number of Islands
Disjoint set
- Union adjacent and reachable points by iterating all entries.
- Count representatives.
In [12]:
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
class Solution1:
@logging_time
def numIslands(self, grid: List[List[str]], show=False) -> int:
par, rnk = {}, {}
def find(x):
if x not in par:
par[x] = x
rnk[x] = 0
return par[x]
if x != par[x]:
par[x] = find(par[x])
return par[x]
def union(x, y):
x, y = find(x), find(y)
if x == y: return
if rnk[x] > rnk[y]:
x, y = y, x
par[x] = y
if rnk[x] == rnk[y]:
rnk[y] += 1
if show: print(np.array(grid))
def adj(i, j):
for x, y in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and int(grid[x][y]):
yield x, y
for i in range(len(grid)):
for j in range(len(grid[0])):
if int(grid[i][j]):
find((i, j))
for x, y in adj(i, j):
union((i, j), (x, y))
if show: visualize_ds(par)
ans = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if int(grid[i][j]) and (i,j) == find((i, j)):
ans += 1
return ans
sol1 = Solution1()
In [13]:
1
2
3
4
5
6
7
# grid = [["1", "1", "1", "1", "0"], ["1", "1", "0", "1", "0"], ["1", "1", "0", "0", "0"], ["0", "0", "0", "0", "0"]]
grid = \
[[1,1,0,0,0],
[1,1,0,0,0],
[0,0,1,0,0],
[0,0,0,1,1]]
print("ans:", sol1.numIslands(grid, verbose=True, show=True))
1
2
3
4
5
[[1 1 0 0 0]
[1 1 0 0 0]
[0 0 1 0 0]
[0 0 0 1 1]]
1
2
3
WorkingTime[numIslands]: 172.88089 ms
ans: 3
DFS
- Mark adjacent reachable grid as seen from start point.
- Count the number of start points.
In [14]:
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
class Solution2:
@logging_time
def numIslands(self, grid: List[List[str]]) -> int:
def adj(i, j):
for x, y in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
if 0 <= x < len(grid) and 0 <= y < len(grid[0]) and int(grid[x][y]):
yield x, y
seen = set()
def dfs(i, j):
seen.add((i, j))
# grid[i][j] = '2'
for x, y in adj(i, j):
if (x, y) not in seen:
dfs(x, y)
ans = 0
for i in range(len(grid)):
for j in range(len(grid[0])):
if int(grid[i][j]) and (i, j) not in seen:
ans += 1
dfs(i, j)
return ans
sol2 = Solution2()
In [18]:
1
2
3
4
5
6
7
grid = \
[[1,1,0,0,0],
[1,1,0,0,0],
[0,0,1,0,0],
[0,0,0,1,1]]
print("ans1:", sol1.numIslands(grid, verbose=True, show=False))
print("ans2:", sol2.numIslands(grid, verbose=True))
1
2
3
4
5
WorkingTime[numIslands]: 0.05245 ms
ans1: 3
WorkingTime[numIslands]: 0.02980 ms
ans2: 3
In [32]:
1
2
3
m, n = 1000, 1000
grid = [[random.randint(0, 1) for i in range(m)] for j in range(n)]
print(np.array(grid))
1
2
3
4
5
6
7
8
[[0 1 0 ... 1 1 0]
[0 1 1 ... 1 0 0]
[1 1 1 ... 0 0 1]
...
[0 1 0 ... 0 0 1]
[0 0 0 ... 1 1 1]
[0 0 0 ... 1 0 1]]
In [33]:
1
2
print("ans1:", sol1.numIslands(grid, verbose=True, show=False))
print("ans2:", sol2.numIslands(grid, verbose=True))
1
2
3
4
5
WorkingTime[numIslands]: 3131.24204 ms
ans1: 66540
WorkingTime[numIslands]: 1263.87072 ms
ans2: 66540
Leave a comment