Skip to content

Commit 4a98a58

Browse files
committed
Number of islands
1 parent 4a0c7c6 commit 4a98a58

File tree

2 files changed

+204
-0
lines changed

2 files changed

+204
-0
lines changed

200.number_of_islands/islands.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# 200. Number of islands
2+
# Topics: 'Array', 'Depth-First Search', 'Breadth-First Search', 'Union Find', 'Matrix'
3+
# Level: 'Medium'
4+
5+
# Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands.
6+
7+
# 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.
8+
9+
# Example 1:
10+
11+
# Input: grid = [
12+
# ["1","1","1","1","0"],
13+
# ["1","1","0","1","0"],
14+
# ["1","1","0","0","0"],
15+
# ["0","0","0","0","0"]
16+
# ]
17+
# Output: 1
18+
19+
# Example 2:
20+
21+
# Input: grid = [
22+
# ["1","1","0","0","0"],
23+
# ["1","1","0","0","0"],
24+
# ["0","0","1","0","0"],
25+
# ["0","0","0","1","1"]
26+
# ]
27+
# Output: 3
28+
29+
# Constraints:
30+
31+
# m == grid.length
32+
# n == grid[i].length
33+
# 1 <= m, n <= 300
34+
# grid[i][j] is '0' or '1'.
35+
36+
from typing import List
37+
38+
class Solution:
39+
def numIslands(self, grid: List[List[str]]) -> int:
40+
ROWS, COLS = len(grid), len(grid[0])
41+
visited = set()
42+
43+
def complete_island(r: int, c: int):
44+
if r < 0 or c < 0:
45+
return
46+
if r == ROWS or c == COLS:
47+
return
48+
if (r, c) in visited:
49+
return
50+
if grid[r][c] == '0':
51+
return
52+
53+
visited.add((r,c))
54+
complete_island(r+1, c)
55+
complete_island(r-1, c)
56+
complete_island(r, c+1)
57+
complete_island(r, c-1)
58+
59+
60+
count = 0
61+
for i in range(ROWS):
62+
for j in range(COLS):
63+
if grid[i][j] == '1' and (i,j) not in visited:
64+
count += 1
65+
complete_island(i, j)
66+
67+
68+
return count
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import unittest
2+
from typing import List
3+
from islands import Solution
4+
5+
class TestNumIslands(unittest.TestCase):
6+
7+
def setUp(self):
8+
self.solution = Solution()
9+
10+
def test_basic_multiple_islands(self):
11+
"""Test case with multiple distinct islands"""
12+
grid = [
13+
["1","1","1","1","0"],
14+
["1","1","0","1","0"],
15+
["1","1","0","0","0"],
16+
["0","0","0","0","0"]
17+
]
18+
self.assertEqual(self.solution.numIslands(grid), 1)
19+
20+
def test_separate_islands(self):
21+
"""Test case with clearly separated islands"""
22+
grid = [
23+
["1","1","0","0","0"],
24+
["1","1","0","0","0"],
25+
["0","0","1","0","0"],
26+
["0","0","0","1","1"]
27+
]
28+
self.assertEqual(self.solution.numIslands(grid), 3)
29+
30+
def test_single_cell_island(self):
31+
"""Test with single cell island"""
32+
grid = [["1"]]
33+
self.assertEqual(self.solution.numIslands(grid), 1)
34+
35+
def test_single_cell_water(self):
36+
"""Test with single cell of water"""
37+
grid = [["0"]]
38+
self.assertEqual(self.solution.numIslands(grid), 0)
39+
40+
def test_all_water(self):
41+
"""Test grid with only water"""
42+
grid = [
43+
["0","0","0"],
44+
["0","0","0"],
45+
["0","0","0"]
46+
]
47+
self.assertEqual(self.solution.numIslands(grid), 0)
48+
49+
def test_all_land(self):
50+
"""Test grid with only land (one big island)"""
51+
grid = [
52+
["1","1","1"],
53+
["1","1","1"],
54+
["1","1","1"]
55+
]
56+
self.assertEqual(self.solution.numIslands(grid), 1)
57+
58+
def test_diagonal_not_connected(self):
59+
"""Test that diagonal cells are not considered connected"""
60+
grid = [
61+
["1","0","1"],
62+
["0","1","0"],
63+
["1","0","1"]
64+
]
65+
self.assertEqual(self.solution.numIslands(grid), 5)
66+
67+
def test_complex_shape(self):
68+
"""Test with complex island shapes"""
69+
grid = [
70+
["1","1","0","0","1"],
71+
["1","0","0","1","1"],
72+
["0","0","1","0","0"],
73+
["0","0","0","1","1"]
74+
]
75+
self.assertEqual(self.solution.numIslands(grid), 4)
76+
77+
def test_snake_island(self):
78+
"""Test with a snake-like connected island"""
79+
grid = [
80+
["1","0","0","0"],
81+
["1","1","0","0"],
82+
["0","1","1","0"],
83+
["0","0","1","1"]
84+
]
85+
self.assertEqual(self.solution.numIslands(grid), 1)
86+
87+
def test_vertical_line(self):
88+
"""Test with vertical line island"""
89+
grid = [
90+
["1"],
91+
["1"],
92+
["1"],
93+
["1"]
94+
]
95+
self.assertEqual(self.solution.numIslands(grid), 1)
96+
97+
def test_horizontal_line(self):
98+
"""Test with horizontal line island"""
99+
grid = [["1","1","1","1"]]
100+
self.assertEqual(self.solution.numIslands(grid), 1)
101+
102+
def test_checkerboard_pattern(self):
103+
"""Test with alternating pattern"""
104+
grid = [
105+
["1","0","1","0"],
106+
["0","1","0","1"],
107+
["1","0","1","0"],
108+
["0","1","0","1"]
109+
]
110+
self.assertEqual(self.solution.numIslands(grid), 8)
111+
112+
def test_large_grid_one_island(self):
113+
"""Test with larger grid containing one island"""
114+
grid = [
115+
["1","1","1","1","1"],
116+
["1","0","0","0","1"],
117+
["1","0","0","0","1"],
118+
["1","0","0","0","1"],
119+
["1","1","1","1","1"]
120+
]
121+
self.assertEqual(self.solution.numIslands(grid), 1)
122+
123+
def test_surrounded_water(self):
124+
"""Test island surrounded by water"""
125+
grid = [
126+
["0","0","0","0","0"],
127+
["0","1","1","1","0"],
128+
["0","1","0","1","0"],
129+
["0","1","1","1","0"],
130+
["0","0","0","0","0"]
131+
]
132+
self.assertEqual(self.solution.numIslands(grid), 1)
133+
134+
135+
if __name__ == '__main__':
136+
unittest.main(verbosity=2)

0 commit comments

Comments
 (0)