-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0305__number_of_islands_2.py
65 lines (47 loc) · 1.69 KB
/
0305__number_of_islands_2.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
"""
LeetCode premium: https://leetcode.com/problems/number-of-islands-ii/
"""
from typing import List, Tuple
from unittest import TestCase
class Solution(TestCase):
def test_it(self):
expected = [1, 2, 2, 2, 2, 2, 2, 1]
positions = [[0, 0], [2, 0], [0, 1], [2, 1], [0, 2], [2, 2], [0, 1], [1, 2]]
self.assertEqual(expected, self.numIslands2(3, 3, positions))
def numIslands2(self, m: int, n: int, positions: List[List[int]]) -> List[int]:
uf = {}
def find(p: Tuple[int, int]) -> Tuple[int, int]:
if p not in uf:
uf[p] = p
if p != uf[p]:
uf[p] = find(uf[p])
return uf[p]
def union_around(p: Tuple[int, int]) -> int:
find(p)
connections = 0
for dr, dc in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
new_row, new_col = p[0] + dr, p[1] + dc
new_p = (new_row, new_col)
if (
new_row < 0 or new_row >= m
or new_col < 0 or new_col >= n
or new_p not in uf
):
continue
connections += union(p, new_p)
return connections
def union(p1: Tuple[int, int], p2: Tuple[int, int]) -> int:
p1root, p2root = find(p1), find(p2)
if p1root == p2root:
return 0
# @todo: optimize by rank
uf[p1root] = p2root
return 1
count = 0
result = []
for p in positions:
p = tuple(p)
if p not in uf:
count += 1 - union_around(p)
result.append(count)
return result