Skip to content

Commit 01ceca0

Browse files
committed
AlgoExpert Remove Islands
1 parent e98a5a3 commit 01ceca0

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,13 +866,16 @@ First column links to the problem in AlgoExpert, second is the problem's difficu
866866
| ----------------------------------- | ------------ | --------------------------------------------- |
867867
| [Insertion Sort][ae&insertion-sort] | 🟢 Easy | [![python](res/py.png)][ae&insertion-sort#py] |
868868
| [Merge Sort][ae&merge-sort] | 🟣 Very Hard | [![python](res/py.png)][ae&merge-sort#py] |
869+
| [Remove Islands][ae&remove-islands] | 🟣 Very Hard | [![python](res/py.png)][ae&remove-islands#py] |
869870

870871
[🔝 Back to Top 🔝](#coding-challenges)
871872

872873
[ae&insertion-sort]: https://www.algoexpert.io/questions/merge-sort
873874
[ae&insertion-sort#py]: algoexpert/insertion-sort.py
874875
[ae&merge-sort]: https://www.algoexpert.io/questions/merge-sort
875876
[ae&merge-sort#py]: algoexpert/merge-sort.py
877+
[ae&remove-islands]: https://www.algoexpert.io/questions/remove-islands
878+
[ae&remove-islands#py]: algoexpert/remove-islands.py
876879

877880
## HackerRank problems
878881

algoexpert/remove-islands.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Remove Islands
2+
# 🟠 Medium
3+
#
4+
# https://www.algoexpert.io/questions/remove-islands
5+
#
6+
# Tags: Array - Matrix - Graph - Depth-First Search
7+
8+
import timeit
9+
from typing import List
10+
11+
12+
# Use depth first search to mark all island cells 4 directionally
13+
# adjacent to a cell in the edge of the matrix as safe, then visit all
14+
# cells in the matrix removing any island that has not been marked as
15+
# safe.
16+
#
17+
# Time complexity: O(m*n) - Where m is the number of rows and n is the
18+
# number of columns.
19+
# Space complexity: O(1) - The exercise asks us to mutate the input
20+
# matrix in place, if we didn't want to we could create a copy using
21+
# O(m*n) memory.
22+
class Solution:
23+
def removeIslands(self, matrix: List[List[int]]) -> List[List[int]]:
24+
NUM_ROWS, NUM_COLS = len(matrix), len(matrix[0])
25+
# Define a function that turns all 1s of a given island into 2s.
26+
def dfs(r: int, c: int) -> None:
27+
# Mark this cell as adjacent to the edge.
28+
matrix[r][c] = 2
29+
dir = [[0, 1], [0, -1], [1, 0], [-1, 0]]
30+
for rc, cc in dir:
31+
tr = r + rc
32+
tc = c + cc
33+
if (
34+
0 <= tr < NUM_ROWS
35+
and 0 <= tc < NUM_COLS
36+
and matrix[tr][tc] == 1
37+
):
38+
dfs(tr, tc)
39+
40+
# Update all 1s adjacent to a border.
41+
for c in range(NUM_COLS):
42+
if matrix[0][c]:
43+
dfs(0, c)
44+
if matrix[NUM_ROWS - 1][c]:
45+
dfs(NUM_ROWS - 1, c)
46+
for r in range(NUM_ROWS):
47+
if matrix[r][0]:
48+
dfs(r, 0)
49+
if matrix[r][NUM_COLS - 1]:
50+
dfs(r, NUM_COLS - 1)
51+
52+
# Remove the islands.
53+
for r in range(NUM_ROWS):
54+
for c in range(NUM_COLS):
55+
if matrix[r][c] == 1:
56+
matrix[r][c] = 0
57+
elif matrix[r][c] == 2:
58+
matrix[r][c] = 1
59+
60+
return matrix
61+
62+
63+
def test():
64+
executors = [Solution]
65+
tests = [
66+
[[[1]], [[1]]],
67+
[
68+
[
69+
[1, 1, 1, 1, 1],
70+
[1, 1, 1, 1, 1],
71+
[1, 1, 1, 1, 1],
72+
[1, 1, 1, 1, 1],
73+
[1, 1, 1, 1, 1],
74+
],
75+
[
76+
[1, 1, 1, 1, 1],
77+
[1, 1, 1, 1, 1],
78+
[1, 1, 1, 1, 1],
79+
[1, 1, 1, 1, 1],
80+
[1, 1, 1, 1, 1],
81+
],
82+
],
83+
[
84+
[
85+
[1, 0, 0, 0, 0, 0],
86+
[0, 1, 0, 1, 1, 1],
87+
[0, 0, 1, 0, 1, 0],
88+
[1, 1, 0, 0, 1, 0],
89+
[1, 0, 1, 1, 0, 0],
90+
[1, 0, 0, 0, 0, 1],
91+
],
92+
[
93+
[1, 0, 0, 0, 0, 0],
94+
[0, 0, 0, 1, 1, 1],
95+
[0, 0, 0, 0, 1, 0],
96+
[1, 1, 0, 0, 1, 0],
97+
[1, 0, 0, 0, 0, 0],
98+
[1, 0, 0, 0, 0, 1],
99+
],
100+
],
101+
[
102+
[
103+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
104+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
105+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
106+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
107+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
108+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
109+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
110+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
111+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
112+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
113+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
114+
[0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
115+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
116+
],
117+
[
118+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
119+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
120+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
121+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
122+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
123+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
124+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
125+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
126+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
127+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
128+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
129+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
130+
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
131+
],
132+
],
133+
]
134+
for executor in executors:
135+
start = timeit.default_timer()
136+
for _ in range(1):
137+
for col, t in enumerate(tests):
138+
sol = executor()
139+
result = sol.removeIslands(t[0])
140+
exp = t[1]
141+
assert result == exp, (
142+
f"\033[93m» {result} <> {exp}\033[91m for"
143+
+ f" test {col} using \033[1m{executor.__name__}"
144+
)
145+
stop = timeit.default_timer()
146+
used = str(round(stop - start, 5))
147+
cols = "{0:20}{1:10}{2:10}"
148+
res = cols.format(executor.__name__, used, "seconds")
149+
print(f"\033[92m» {res}\033[0m")
150+
151+
152+
test()

0 commit comments

Comments
 (0)