Skip to content

Commit 8da408b

Browse files
committed
Island perimeter
1 parent 950172a commit 8da408b

File tree

2 files changed

+242
-0
lines changed

2 files changed

+242
-0
lines changed

463.island_perimeter/perimeter.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# 463. Island perimeter
2+
# Topics: 'Matrix', 'Array', 'Depth-First Search', 'Breadth-First Search'
3+
4+
# You are given row x col grid representing a map where grid[i][j] = 1 represents land and grid[i][j] = 0 represents water.
5+
6+
# Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells).
7+
8+
# The island doesn't have "lakes", meaning the water inside isn't connected to the water around the island. One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island.
9+
10+
11+
12+
# Example 1:
13+
14+
# Input: grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
15+
# Output: 16
16+
# Explanation: The perimeter is the 16 yellow stripes in the image above.
17+
18+
# Example 2:
19+
20+
# Input: grid = [[1]]
21+
# Output: 4
22+
23+
# Example 3:
24+
25+
# Input: grid = [[1,0]]
26+
# Output: 4
27+
28+
29+
30+
# Constraints:
31+
32+
# row == grid.length
33+
# col == grid[i].length
34+
# 1 <= row, col <= 100
35+
# grid[i][j] is 0 or 1.
36+
# There is exactly one island in grid.
37+
38+
from collections import deque
39+
from typing import List
40+
41+
class Solution:
42+
def islandPerimeter(self, grid: List[List[int]]) -> int:
43+
ROWS, COLS = len(grid), len(grid[0])
44+
perm = 0
45+
q = deque()
46+
visit = set()
47+
for i in range (len(grid)):
48+
for j in range (len(grid[i])):
49+
if grid[i][j] == 1:
50+
q.append((i,j))
51+
break
52+
53+
while q:
54+
row, col = q.popleft()
55+
if min(row, col) < 0:
56+
continue
57+
if row == ROWS or col == COLS:
58+
continue
59+
if (row,col) in visit:
60+
continue
61+
if grid[row][col] != 1:
62+
continue
63+
visit.add((row,col))
64+
perm += self.calculate(grid, row, col)
65+
q.append((row+1, col))
66+
q.append((row-1, col))
67+
q.append((row, col+1))
68+
q.append((row, col-1))
69+
70+
return perm
71+
72+
def calculate(self, grid: List[List[int]], row: int, col: int) -> int:
73+
p = 4
74+
ROWS, COLS = len(grid), len(grid[0])
75+
directions = [[1,0],[-1,0],[0,1],[0,-1]]
76+
for dr, dc in directions:
77+
if min(row+dr,col+dc) < 0:
78+
continue
79+
if row+dr == ROWS or col+dc == COLS:
80+
continue
81+
if grid[row+dr][col+dc] == 1:
82+
p-=1
83+
return p
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import unittest
2+
from collections import deque
3+
from typing import List
4+
from perimeter import Solution
5+
6+
class TestIslandPerimeter(unittest.TestCase):
7+
8+
def setUp(self):
9+
self.solution = Solution()
10+
11+
def test_single_cell(self):
12+
"""Test with a single land cell"""
13+
grid = [[1]]
14+
self.assertEqual(self.solution.islandPerimeter(grid), 4)
15+
16+
def test_single_cell_with_water(self):
17+
"""Test single land cell surrounded by water"""
18+
grid = [
19+
[0, 0, 0],
20+
[0, 1, 0],
21+
[0, 0, 0]
22+
]
23+
self.assertEqual(self.solution.islandPerimeter(grid), 4)
24+
25+
def test_two_cells_horizontal(self):
26+
"""Test two adjacent cells horizontally"""
27+
grid = [[1, 1]]
28+
self.assertEqual(self.solution.islandPerimeter(grid), 6)
29+
30+
def test_two_cells_vertical(self):
31+
"""Test two adjacent cells vertically"""
32+
grid = [
33+
[1],
34+
[1]
35+
]
36+
self.assertEqual(self.solution.islandPerimeter(grid), 6)
37+
38+
def test_example_1(self):
39+
"""Test LeetCode Example 1"""
40+
grid = [
41+
[0, 1, 0, 0],
42+
[1, 1, 1, 0],
43+
[0, 1, 0, 0],
44+
[1, 1, 0, 0]
45+
]
46+
self.assertEqual(self.solution.islandPerimeter(grid), 16)
47+
48+
def test_example_2(self):
49+
"""Test LeetCode Example 2"""
50+
grid = [[1]]
51+
self.assertEqual(self.solution.islandPerimeter(grid), 4)
52+
53+
def test_example_3(self):
54+
"""Test LeetCode Example 3"""
55+
grid = [[1, 0]]
56+
self.assertEqual(self.solution.islandPerimeter(grid), 4)
57+
58+
def test_square_island(self):
59+
"""Test 2x2 square island"""
60+
grid = [
61+
[1, 1],
62+
[1, 1]
63+
]
64+
self.assertEqual(self.solution.islandPerimeter(grid), 8)
65+
66+
def test_3x3_square_island(self):
67+
"""Test 3x3 square island"""
68+
grid = [
69+
[1, 1, 1],
70+
[1, 1, 1],
71+
[1, 1, 1]
72+
]
73+
self.assertEqual(self.solution.islandPerimeter(grid), 12)
74+
75+
def test_l_shaped_island(self):
76+
"""Test L-shaped island"""
77+
grid = [
78+
[1, 0],
79+
[1, 0],
80+
[1, 1]
81+
]
82+
self.assertEqual(self.solution.islandPerimeter(grid), 10)
83+
84+
def test_island_at_corner(self):
85+
"""Test island starting at top-left corner"""
86+
grid = [
87+
[1, 1, 0],
88+
[1, 0, 0],
89+
[0, 0, 0]
90+
]
91+
self.assertEqual(self.solution.islandPerimeter(grid), 8)
92+
93+
def test_island_at_bottom_right(self):
94+
"""Test island at bottom-right corner"""
95+
grid = [
96+
[0, 0, 0],
97+
[0, 0, 1],
98+
[0, 1, 1]
99+
]
100+
self.assertEqual(self.solution.islandPerimeter(grid), 8)
101+
102+
def test_long_horizontal_line(self):
103+
"""Test long horizontal line of land"""
104+
grid = [[1, 1, 1, 1, 1]]
105+
self.assertEqual(self.solution.islandPerimeter(grid), 12)
106+
107+
def test_long_vertical_line(self):
108+
"""Test long vertical line of land"""
109+
grid = [
110+
[1],
111+
[1],
112+
[1],
113+
[1],
114+
[1]
115+
]
116+
self.assertEqual(self.solution.islandPerimeter(grid), 12)
117+
118+
def test_plus_shaped_island(self):
119+
"""Test plus/cross shaped island"""
120+
grid = [
121+
[0, 1, 0],
122+
[1, 1, 1],
123+
[0, 1, 0]
124+
]
125+
self.assertEqual(self.solution.islandPerimeter(grid), 12)
126+
127+
def test_complex_shape(self):
128+
"""Test complex irregular shape"""
129+
grid = [
130+
[1, 1, 0, 0],
131+
[1, 1, 1, 0],
132+
[0, 0, 1, 0],
133+
[0, 0, 1, 1]
134+
]
135+
self.assertEqual(self.solution.islandPerimeter(grid), 16)
136+
137+
def test_snake_shape(self):
138+
"""Test snake-like shape"""
139+
grid = [
140+
[1, 1, 0],
141+
[0, 1, 0],
142+
[0, 1, 1]
143+
]
144+
self.assertEqual(self.solution.islandPerimeter(grid), 12)
145+
146+
def test_all_water_except_one(self):
147+
"""Test large grid with single land cell"""
148+
grid = [
149+
[0, 0, 0, 0],
150+
[0, 0, 0, 0],
151+
[0, 0, 1, 0],
152+
[0, 0, 0, 0]
153+
]
154+
self.assertEqual(self.solution.islandPerimeter(grid), 4)
155+
156+
157+
if __name__ == '__main__':
158+
# Run tests with verbose output
159+
unittest.main(verbosity=2)

0 commit comments

Comments
 (0)