给定一个二维整数的网格地图,网格中1代表陆地,0代表水域。网格单元的连接方式是水平和垂直。网格完全被水域包围,其中有一个岛屿。这个岛屿内部没有水域。每个单元格是长度为1的正方形。网格本身是长和宽不超过100的矩阵。请确定这个岛屿的周长
Example:
[[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]
Answer: 16
Explanation: The perimeter is the 16 yellow stripes in the image below:
1、本题目标是求如上图中的深色区域的周长,难点在于需要判断每一个单元格是否与矩阵的周长重叠。为了解决这个问题,可以将矩阵向四周扩充一个单元格,扩充的单元格值为1,将长和宽分别加1(4 x 5的矩阵 -> 5 x 6的矩阵)。
def islandPerimeter(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
if not grid or not grid[0]:
return 0
premeter = 0
height = len(grid) #扩充前矩阵的高和宽
width = len(grid[0])
for i in range(height): #矩阵扩充
grid[i].insert(0, 0)
grid[i].append(0)
upAndDown = [0] * (width + 2)
grid.insert(0, upAndDown)
grid.append(upAndDown)
for i in range(1, height + 1):
for j in range(1, width + 1):
if grid[i][j] == 1: #计算岛屿周长
if grid[i][j - 1] == 0:
premeter += 1
if grid[i][j + 1] == 0:
premeter += 1
if grid[i - 1][j] == 0:
premeter += 1
if grid[i + 1][j] == 0:
premeter += 1
return premeter
优雅写法(参考他人)
def islandPerimeter(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
grid = [[0] * len(grid[0])] + grid + [[0] * len(grid[0])]
grid = [[0] + g + [0] for g in grid]
sum = 0
for i in range(1, len(grid) - 1):
for j in range(1, len(grid[0]) - 1):
if grid[i][j] == 1:
a = grid[i - 1][j] == 1
b = grid[i + 1][j] == 1
c = grid[i][j - 1] == 1
d = grid[i][j + 1] == 1
sum += 4 - (a + b + c + d)
return sum
2、不扩充矩阵,用if语句判断边界
def islandPerimeter(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
premeter=0
for i in range(len(grid)):
for j in range(len(grid[0])):
if grid[i][j]==1:
if i==0:
premeter+=1
elif grid[i-1][j]==0:
premeter+=1
if i==(len(grid)-1):
premeter+=1
elif grid[i+1][j]==0:
premeter+=1
if j==0:
premeter+=1
elif grid[i][j-1]==0:
premeter+=1
if j==(len(grid[0])-1):
premeter+=1
elif grid[i][j+1]==0:
premeter+=1
return premeter
3、除却第一行和第一列,判断每一个单元格。如果当前单元格[i,j]代表陆地,则周长加4。如果该单元格[i ,j]正上方单元格[i-1 ,j]代表陆地,则周长减2。如果该单元格[i ,j]左边单元格[i, j-1]代表陆地,则周长减2。(参考他人)
def islandPerimeter(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
perimeter = 0
for i in range(len(grid)):
for j in range(len(grid[i])):
if grid[i][j] == 1:
perimeter += 4
if i - 1 >= 0 and grid[i - 1][j] == 1:
perimeter -= 2
if j - 1 >= 0 and grid[i][j - 1] == 1:
perimeter -= 2
return perimeter
算法题来自:https://leetcode-cn.com/problems/island-perimeter/description/