😡😡😡
声明:
算法基于https://labuladong.github.io/
同步git地址:https://github.com/muxintong/break-algorithm/
python语言实现
岛屿问题:
https://labuladong.github.io/algo/4/29/108/
200.number-of-islands
695.max-area-of-island
1020.number-of-enclaves
1254.number-of-closed-islands
1905.count-sub-islands
😡😡😡
200.number-of-islands
from typing import List
class Solution:
# 岛屿:'1'
# 海水:'0'
def numIslands(self, grid: List[List[str]]) -> int:
m = len(grid)
n = len(grid[0])
# 淹没grid[i][j]上下左右的岛屿
def dfs(i: int, j: int):
if i < 0 or j < 0 or i > m-1 or j > n-1:
return
if grid[i][j] == '0':
return
elif grid[i][j] == '1':
# NOTE:直接将grid[i][j]这块陆地的值置为海水'0'可避免标记数组visited的使用
grid[i][j] = '0'
dfs(i - 1, j) # 淹没上陆地
dfs(i + 1, j) # 淹没下陆地
dfs(i, j - 1) # 淹没左陆地
dfs(i, j + 1) # 淹没右陆地
res = 0
# 遍历grid
for i in range(m):
for j in range(n):
if grid[i][j]=='1':
res += 1
dfs(i, j)
return res
def main():
# Input: grid = [
# ["1","1","1","1","0"],
# ["1","1","0","1","0"],
# ["1","1","0","0","0"],
# ["0","0","0","0","0"]
# ]
# Output: 1
solution1 = Solution()
print(solution1.numIslands(grid = [
["1","1","1","1","0"],
["1","1","0","1","0"],
["1","1","0","0","0"],
["0","0","0","0","0"]
]))
print('---')
# Input: grid = [
# ["1","1","0","0","0"],
# ["1","1","0","0","0"],
# ["0","0","1","0","0"],
# ["0","0","0","1","1"]
# ]
# Output: 3
solution2 = Solution()
print(solution2.numIslands(grid = [
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]))
if __name__ == '__main__':
main()
😡😡😡
695.max-area-of-island
from typing import List
class Solution:
# 陆地:1
# 海水:0
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
m = len(grid)
n = len(grid[0])
# 递归淹没陆地grid[i][j]==1上下左右四周的所有陆地,并返回被淹没的岛屿的面积
def dfs(i: int, j: int) -> int:
if i < 0 or j < 0 or i > m - 1 or j > n - 1:
return 0
if grid[i][j] == 0:
return 0
elif grid[i][j] == 1:
grid[i][j] = 0 # 如果grid[i][j]==1是陆地,将其变成海水,标记为已经访问处理过
return dfs(i - 1, j) + dfs(i + 1, j) + dfs(i, j - 1) + dfs(i, j + 1) + 1
# 非封闭岛屿问题,无需处理上下左右四条边界线,直接遍历grid,处理是陆地的grid[i][j]即可
max_area = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
max_area = max(max_area, dfs(i, j))
return max_area
def main():
# Input: grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
# Output: 6
solution1 = Solution()
print(solution1.maxAreaOfIsland(
grid=[[0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0],
[0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0]]))
# Input: grid = [[0,0,0,0,0,0,0,0]]
# Output: 0
solution2 = Solution()
print(solution2.maxAreaOfIsland(grid=[[0, 0, 0, 0, 0, 0, 0, 0]]))
# Input [[1,1,0,1,1],[1,0,0,0,0],[0,0,0,0,1],[1,1,0,1,1]]
# Output 4
# Expected 3
solution3 = Solution()
print(solution3.maxAreaOfIsland([[1,1,0,1,1],[1,0,0,0,0],[0,0,0,0,1],[1,1,0,1,1]]))
if __name__ == '__main__':
main()
😡😡😡
1020.number-of-enclaves
from typing import List
class Solution:
# 0 sea
# 1 land
def numEnclaves(self, grid: List[List[int]]) -> int:
# 淹没grid[i][j]上下左右的岛屿,并返回被淹没的岛屿面积
def dfs(i: int, j: int) -> int:
# 递归出口
if i < 0 or j < 0 or i > m - 1 or j > n - 1:
return 0
# 选择grid[i][j]判断:land(1) or sea(0)?
if grid[i][j] == 0:
return 0
elif grid[i][j] == 1:
grid[i][j] = 0
# return 1
# NOTE:除了被淹没的上下左右四块岛屿的面积,还需加上被淹没的grid[i][j]的面积1
return dfs(i - 1, j) + dfs(i + 1, j) + dfs(i, j - 1) + dfs(i, j + 1) + 1
m = len(grid)
n = len(grid[0])
# 因所求为封闭岛屿面积,还需淹没上下+左右 四条边界线上的所有岛屿
for j in range(n):
dfs(0, j)
dfs(m - 1, j)
for i in range(m):
dfs(i, 0)
dfs(i, n - 1)
# 遍历grid,淹没grid[i][j]是陆地1的上下左右四周的所有岛屿
res = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 1:
res += dfs(i, j)
return res
def main():
# Input: grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
# Output: 3
solution1 = Solution()
print(solution1.numEnclaves(grid=[[0, 0, 0, 0], [1, 0, 1, 0], [0, 1, 1, 0], [0, 0, 0, 0]]))
# Input: grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
# Output: 0
solution2 = Solution()
print(solution2.numEnclaves(grid=[[0, 1, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 0, 0]]))
if __name__ == '__main__':
main()
😡😡😡
1254.number-of-closed-islands
from typing import List
class Solution:
# sea: 1
# land: 0
def closedIsland(self, grid: List[List[int]]) -> int:
m = len(grid)
n = len(grid[0])
def dfs(i: int, j: int):
# 递归出口
if i < 0 or j < 0 or i > m - 1 or j > n - 1:
return
# 选择grid[i][j]判断为:0 or 1
if grid[i][j] == 1:
return
elif grid[i][j] == 0:
grid[i][j] = 1 # 对于是陆地0的岛屿直接将其变成海水1,可避免visited数组的使用
dfs(i - 1, j) # 淹没上陆地
dfs(i + 1, j) # 淹没下陆地
dfs(i, j - 1) # 淹没左陆地
dfs(i, j + 1) # 淹没右陆地
# 淹没上下边界的岛屿
for j in range(n):
dfs(0, j) # 淹上
dfs(m - 1, j) # 淹下
# 淹没左右边界的岛屿
for i in range(m):
dfs(i, 0) # 淹左
dfs(i, n - 1) # 淹右
# 淹没边界岛屿后剩下的岛屿数量即为所求
res = 0
for i in range(m):
for j in range(n):
if grid[i][j] == 0:
res += 1
# 因求岛屿的数量,故与陆地0待遇数量加1,并递归【淹没】该陆地周围(上下左右)的所有陆地即可
dfs(i, j)
return res
def main():
# Input: grid = [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]]
# Output: 2
solution1 = Solution()
print(solution1.closedIsland(grid = [[1,1,1,1,1,1,1,0],[1,0,0,0,0,1,1,0],[1,0,1,0,1,1,1,0],[1,0,0,0,0,1,0,1],[1,1,1,1,1,1,1,0]]))
print('---')
# Input: grid = [[0,0,1,0,0],[0,1,0,1,0],[0,1,1,1,0]]
# Output: 1
solution2 = Solution()
print(solution2.closedIsland(grid = [[0,0,1,0,0],[0,1,0,1,0],[0,1,1,1,0]]))
if __name__ == '__main__':
main()
😡😡😡
1905.count-sub-islands
from typing import List
class Solution:
# 陆地:1
# 海水:0
# core mind:返回grid2中是grid1的子岛屿的个数,故以grid2为遍历主体,他的【总岛屿个数 - 不是1的子岛屿个数】即为所求
# step:
# (1)2中不是1的子岛屿:即grid2[i][j]为1,但grid1[i][j]为0,调用dfs将这样的陆地淹没为岛屿。
# (2)dfs 求解grid2中岛屿的个数即为所求
def countSubIslands(self, grid1: List[List[int]], grid2: List[List[int]]) -> int:
m = len(grid2)
n = len(grid2[0])
def dfs(i: int, j: int):
if i < 0 or j < 0 or i > m - 1 or j > n - 1:
return
if grid2[i][j] == 0:
return
elif grid2[i][j] == 1:
grid2[i][j] = 0
dfs(i - 1, j)
dfs(i + 1, j)
dfs(i, j - 1)
dfs(i, j + 1)
# (1)将2中不符合题意的岛屿淹没为海水
for i in range(m):
for j in range(n):
if grid2[i][j] == 1 and grid1[i][j] == 0:
dfs(i, j)
# (2)对2直接调用dfs即为所求
res = 0
for i in range(m):
for j in range(n):
if grid2[i][j] == 1:
res += 1
dfs(i, j)
return res
def main():
# Input: grid1 = [[1,1,1,0,0],[0,1,1,1,1],[0,0,0,0,0],[1,0,0,0,0],[1,1,0,1,1]], grid2 = [[1,1,1,0,0],[0,0,1,1,1],[0,1,0,0,0],[1,0,1,1,0],[0,1,0,1,0]]
# Output: 3
solution1 = Solution()
print(solution1.countSubIslands(
grid1=[[1, 1, 1, 0, 0], [0, 1, 1, 1, 1], [0, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 1, 0, 1, 1]],
grid2=[[1, 1, 1, 0, 0], [0, 0, 1, 1, 1], [0, 1, 0, 0, 0], [1, 0, 1, 1, 0], [0, 1, 0, 1, 0]]))
# Input: grid1 = [[1,0,1,0,1],[1,1,1,1,1],[0,0,0,0,0],[1,1,1,1,1],[1,0,1,0,1]], grid2 = [[0,0,0,0,0],[1,1,1,1,1],[0,1,0,1,0],[0,1,0,1,0],[1,0,0,0,1]]
# Output: 2
solution2 = Solution()
print(solution2.countSubIslands(
grid1=[[1, 0, 1, 0, 1], [1, 1, 1, 1, 1], [0, 0, 0, 0, 0], [1, 1, 1, 1, 1], [1, 0, 1, 0, 1]],
grid2=[[0, 0, 0, 0, 0], [1, 1, 1, 1, 1], [0, 1, 0, 1, 0], [0, 1, 0, 1, 0], [1, 0, 0, 0, 1]]))
if __name__ == '__main__':
main()