0463. Island Perimeter#
Problem#
You are given row x col
grid representing a map where grid[i][j] = 1
represents land and grid[i][j] = 0
represents water.
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).
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.
Examples#
Example 1:
Input: grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
Output: 16
Explanation: The perimeter is the 16 yellow stripes in the image above.Input: image
Example 2:
Input: grid = [[1]]
Output: 4
Example 3:
Input: grid = [[1,0]]
Output: 4
Constraints:#
m == image.length
n == image[i].length
1 <= m, n <= 50
0 <= image[i][j], color < 216
0 <= sr < m
0 <= sc < n
Analysis#
how to calculate perimeter? -> each land cell will contribute
4 - len(adj)
to the whole perimeter, where theadj
is the adjacent land cells of current land cell.How to get all land cells as one island?
Flow:
repeatly do:
traverse each land cell
calculate the number of its adjacent land cells
get total perimeter = 4 * number of land cells - the total number of the adjacenet land cells for each land cell
Assumptions:
Only one island: as long as we find the first land cell, we can run BFS or DFS to traverse all the land cells
No lake
Solution#
"""A solution using DFS"""
def solution(grid):
m, n = len(grid), len(grid[0])
# get the first land cell
first = []
r = 0
while r < m:
c = 0
# move column wise
while c < n:
if grid[r][c] == 0:
c += 1
else:
first = (r, c)
break
r += 1
#
if len(first) < 1:
return 0
# traverse from the first detected land cell
# dfs
label = 2
def dfs(grid, sr, sc, num_lands, num_adjs):
# if connected:
if grid[sr][sc] == 1:
grid[sr][sc] = label
num_lands += 1
num_adjs += get_num_adjs(grid, sr, sc)
# dfs
if sr > 0:
num_lands, num_adjs = dfs(grid, sr - 1, sc, num_lands, num_adjs)
if sr < m - 1:
num_lands, num_adjs = dfs(grid, sr + 1, sc, num_lands, num_adjs)
if sc > 0:
num_lands, num_adjs = dfs(grid, sr, sc - 1, num_lands, num_adjs)
if sc < n - 1:
num_lands, num_adjs = dfs(grid, sr, sc + 1, num_lands, num_adjs)
return num_lands, num_adjs
def get_num_adjs(grid, sr, sc):
# up
adjs = []
num_adjs = 0
if sr > 0:
adjs.append((sr-1, sc))
if sr < m - 1:
adjs.append((sr+1, sc))
if sc > 0:
adjs.append((sr, sc-1))
if sc < n - 1:
adjs.append((sr, sc+1))
for r, c in adjs:
if grid[r][c] == 1 or grid[r][c] == 2:
num_adjs += 1
return num_adjs
num_lands, num_adjs = dfs(grid, first[0], first[1], 0, 0)
print(num_lands, num_adjs)
perim = 4*num_lands - num_adjs
return perim
# tests
grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]]
print(solution(grid))
grid = [[1]]
print(solution(grid))
grid = [[1,0]]
print(solution(grid))
7 12
16
1 0
4
1 0
4