目录
任务
200. 岛屿数量
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
思路
总的逻辑是,每遇到一个新的岛屿,就将计数加1,具体的遍历格子则使用dfs和bfs去遍历陆地,对于每一个格子,都进行dfs或bfs的遍历,
- 当前为水,不统计计数,继续下一个格子的处理
- 当前为已经遍历过的岛屿,不统计计数,继续下一个格子的处理
- 遇到新大陆(未访问过的大陆格子),则对该格子进行遍历以找到与该格子相关的整个岛屿
具体单个岛屿的遍历,实现既可以用dfs,也可以用bfs。
对于dfs,每遇到新的格子(未访问过的)且为陆地则标记并递归遍历,这里隐含着,如果遇到不是陆地的地方则进行下一个方向的处理。如此,可以访问一个整岛屿,将其相关格子标记为True。
对于bfs,实际与bfs同理,只是遍历的流程是按照层去遍历,也是遍历一整个岛屿,将整个岛屿的格子标记为True。需要注意的点是,在每次加入队列时,都需要标记格子为True,原因是为了不重复访问,节省时间,具体更详细的原因可以去看第十一章 图论 Part1的内容。
下面给出dfs和bfs解决这个问题的代码
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
visited = [[False] * len(grid[0]) for _ in range(len(grid))]
result = 0
for i in range(len(grid)): #以每个格子为起点进行遍历
for j in range(len(grid[0])):
if visited[i][j]==False and grid[i][j] == '1': #为新大陆时,累加结果
result += 1
#self.dfs(grid,visited,i,j) #按深度优先遍历标记某岛屿
self.bfs(grid,visited,i,j) #按深度优先遍历标记某岛屿
return result
def dfs(self,grid,visited,x,y):
dir = [(1,0),(0,1),(-1,0),(0,-1)] #逆时针四个方向
visited[x][y] = True # 由调用者(包含外部和自身)保证了该格子为访问过的陆地!
for i in range(4):
nextX = x + dir[i][0]
nextY = y + dir[i][1]
if nextX < 0 or nextY<0 or nextX>=len(grid) or nextY>=len(grid[0]):
continue
if visited[nextX][nextY] == False and grid[nextX][nextY] == '1':
self.dfs(grid,visited,nextX,nextY)
from collections import deque
def bfs(self,grid,visited,x,y):
dir = [(1,0),(0,1),(-1,0),(0,-1)] #逆时针四个方向
que = deque()
que.append((x,y))
visited[x][y] = True
while(que):
curX,curY = que.popleft()
for i in range(4):
nextX = curX + dir[i][0]
nextY = curY + dir[i][1]
if nextX < 0 or nextY<0 or nextX>=len(grid) or nextY>=len(grid[0]):
continue
if visited[nextX][nextY] == False and grid[nextX][nextY] == '1':
que.append((nextX,nextY))
visited[nextX][nextY] =True
695. 岛屿的最大面积
给你一个大小为 m x n 的二进制矩阵 grid 。
岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。
岛屿的面积是岛上值为 1 的单元格的数目。
计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。
思路
如果理解了上一题,本题就可以直接解决,本题求的是岛屿面积,累计的值就是某一个岛屿的面积,就在dfs或者bfs中累计,然后在主函数中取最大的岛屿面积即可。
下面给出dfs和bfs的方法
class Solution:
def __init__(self):
self.count = 0
def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
visited = [[False] * len(grid[0]) for _ in range(len(grid))]
result = 0
for i in range(len(grid)): #以每个格子为起点进行遍历
for j in range(len(grid[0])):
if visited[i][j]==False and grid[i][j] == 1: #为新大陆时,累加结果
self.count = 0
#self.dfs(grid,visited,i,j) #按深度优先遍历标记某岛屿
self.bfs(grid,visited,i,j) #按深度优先遍历标记某岛屿
result = max(result,self.count)
return result
def dfs(self,grid,visited,x,y):
dir = [(1,0),(0,1),(-1,0),(0,-1)] #逆时针四个方向
visited[x][y] = True # 由调用者(包含外部和自身)保证了该格子为访问过的陆地!
self.count += 1
for i in range(4):
nextX = x + dir[i][0]
nextY = y + dir[i][1]
if nextX < 0 or nextY<0 or nextX>=len(grid) or nextY>=len(grid[0]):
continue
if visited[nextX][nextY] == False and grid[nextX][nextY] == 1: #未访问过的陆地则继续访问(直到遍历完整个单独的岛屿)
self.dfs(grid,visited,nextX,nextY)
from collections import deque
def bfs(self,grid,visited,x,y):
dir = [(1,0),(0,1),(-1,0),(0,-1)] #逆时针四个方向
que = deque()
que.append((x,y))
visited[x][y] = True
self.count += 1
while(que):
curX,curY = que.popleft()
for i in range(4):
nextX = curX + dir[i][0]
nextY = curY + dir[i][1]
if nextX < 0 or nextY<0 or nextX>=len(grid) or nextY>=len(grid[0]):
continue
if visited[nextX][nextY] == False and grid[nextX][nextY] == 1: #未访问过的陆地则继续访问(直到遍历完整个单独的岛屿)
que.append((nextX,nextY))
visited[nextX][nextY] =True
self.count+=1
标签:图论,遍历,第十一章,self,Part2,grid,visited,nextX,nextY
From: https://www.cnblogs.com/haohaoscnblogs/p/18398514