1、题目描述:
2、题解:
方法1:BFS
BFS 的几个主要步骤:
1、肯定会用到 deque 的结构用来模拟队列,BFS精髓也在这里。
2、队列里肯定是有一个初始点
3、然后每次处理从队列中出队一个元素
4、对元素进行扩张(具体如何扩张需要根据题目要求,一般是上下左右四个方向,本题是算上斜向共8个方向)
5、对于扩张后满足某条件的点再进行处理,根据需要进入队列,进入队列的点就是扩到下一层的点(不同题目需要
处理的方法不同,大家灵活运用)
6、然后接着循环处理 deque 中的元素,直到 deque 为空,则代表所有点都已经完成扩张
7、最后根据题目要求输出结果(当然这已经不属于 BFS 模板的范围了)
代码如下:
class Solution:
def pondSizes(self, land: List[List[int]]) -> List[int]:
# BFS
res = []
for row in range(len(land)):
for col in range(len(land[0])):
if land[row][col] == 0:
temp = collections.deque()
temp_count = 1
land[row][col] = -1 #将访问的点进行标记
temp.append([row,col])
while len(temp) > 0:
x,y = temp.popleft()
for new_x,new_y in [[x + 1,y],[x - 1,y],[x + 1,y + 1],[x - 1, y + 1],\
[x + 1, y - 1],[x - 1,y - 1],[x, y + 1],[x, y - 1]]:
if 0 <= new_x < len(land) and 0 <= new_y < len(land[0]) and land[new_x][new_y] == 0:
temp_count += 1
land[new_x][new_y] = -1
temp.append([new_x,new_y])
res.append(temp_count)
return sorted(res)
或者:
class Solution:
def pondSizes(self, land: List[List[int]]) -> List[int]:
# BFS,剪枝
res = []
direction = [(1,0),(-1,0),(1,1),(0,1),(-1,1),(1,-1),(0,-1),(-1,-1)] #8个方向
visited = [[0 for _ in range(len(land[0]))] for _ in range(len(land))]
for row in range(len(land)):
for col in range(len(land[0])):
if land[row][col] == 0 and visited[row][col] == 0: #为水域,并且未被访问
temp = collections.deque()
temp_count = 1
visited[row][col] = 1 #将访问的点进行标记
temp.append([row,col])
while len(temp) > 0:
x,y = temp.popleft()
for i ,j in direction:
new_x,new_y = x + i,y + j
if 0 <= new_x < len(land) and 0 <= new_y < len(land[0]) and land[new_x][new_y] == 0 and visited[new_x][new_y] == 0:
temp_count += 1
visited[new_x][new_y] = 1
temp.append([new_x,new_y])
res.append(temp_count)
return sorted(res)
方法2:DFS
DFS+剪枝
用seen 保存已经遍历的池塘
class Solution:
def pondSizes(self, land: List[List[int]]) -> List[int]:
# DFS
n, m = len(land), len(land[0])
self.direction = [(0, 1), (1, 0), (1, 1), (-1, -1), (0, -1), (-1, 0), (-1, 1), (1, -1)] # 8个方向
self.seen = [[0] * m for _ in range(n)]
res = []
for i in range(n):
for j in range(m):
if self.seen[i][j] == 1 or land[i][j] != 0:
continue
else: # 仅当遇见没遍历过的池塘时开始dfs
self.seen[i][j] = 1
res.append(self.dfs(land, i, j))
return sorted(res)
def dfs(self, land, x, y):
n, m = len(land), len(land[0])
res = 1 # 因为只有当为池塘时才会进行搜索
for item in self.direction:
i, j = item
new_x, new_y = x + i, y + j
if new_x >= 0 and new_x < n and new_y >= 0 and new_y < m and self.seen[new_x][new_y] == 0:
self.seen[new_x][new_y] = 1
if land[new_x][new_y] == 0:
res += self.dfs(land, new_x, new_y)
return res
3、复杂度分析:
方法1:
时间复杂度:O()
空间复杂度:O()
方法2:
时间复杂度:O()
空间复杂度:O()