309-魔幻世界中的安全区计算
问题描述
小F被神秘力量带入了一个魔幻世界,这里危机四伏。为了在异世界中生存,小F需要找到安全区。异世界可以被表示为一个大小为 n x m 的二维数组,每个格子的值代表该位置的危险程度。
小F的能力值为 X,当某个格子的危险程度小于等于 X 时,这个格子是安全的。如果多个安全的格子相邻(上下左右连通),它们可以构成一个安全区。你需要帮助小F计算出一共有多少个安全区。
以下是根据题目要求编写代码的思路以及对应的代码实现:
一、整体思路
-
数据表示与初始化
- 我们需要处理一个大小为 的二维数组来表示异世界。首先要考虑如何表示这个二维数组以及相关的变量,如小F的能力值 。
- 我们可以定义一个函数,接受 、、 和表示异世界危险程度的二维数组作为参数。
-
安全区的判定与搜索
- 对于每个格子,需要判断它是否是安全的(即危险程度小于等于 )。如果是安全的且未被标记过,那么它可能是一个新的安全区的起点。
- 采用深度优先搜索(DFS)或者广度优先搜索(BFS)来标记属于同一个安全区的所有格子。这里以DFS为例,从一个安全格子开始,递归地访问它的上下左右相邻格子,如果相邻格子也是安全的且未被访问过,就继续递归访问这个相邻格子,直到没有更多的相邻安全格子为止。
-
安全区数量的统计
- 在遍历二维数组的过程中,每发现一个新的未被访问的安全格子并完成对其所在安全区的标记,就将安全区的数量加1。
二、代码实现
def solution(n: int, m: int, X: int, a: list[list[int]]) -> int:
def dfs(x: int, y: int):
# 判断坐标是否合法且该格子安全且未被访问
if 0 <= x < n and 0 <= y < m and a[x][y] <= X and not visited[x][y]:
visited[x][y] = True
# 递归访问上下左右相邻格子
dfs(x - 1, y)
dfs(x + 1, y)
dfs(x, y - 1)
dfs(x, y + 1)
visited = [[False] * m for _ in range(n)]
safe_zone_count = 0
for i in range(n):
for j in range(m):
if a[i][j] <= X and not visited[i][j]:
safe_zone_count += 1
dfs(i, j)
return safe_zone_count
三、代码解析
-
dfs函数- 这是一个递归函数,用于深度优先搜索。它的目的是标记从给定坐标 开始的同一个安全区内的所有格子。
- 首先,它进行边界检查,确保坐标 在二维数组的合法范围内,并且该格子的危险程度小于等于 ,同时这个格子还没有被访问过。如果满足这些条件,就将这个格子标记为已访问(
visited[x][y]=True)。 - 然后,它递归地调用自身来访问这个格子的上下左右相邻格子。例如,
dfs(x - 1,y)会访问当前格子上方的格子(假设坐标系统中,上方格子的 坐标比当前格子小1)。这种递归调用会持续进行,直到没有更多符合条件的相邻格子为止。
-
主逻辑部分
- 在主逻辑中,首先创建了一个与二维数组 大小相同的布尔型二维数组
visited,用于标记每个格子是否被访问过。初始时,所有元素都为False。 - 然后,使用两层嵌套的循环遍历二维数组 。对于每个格子,如果它是安全的(
a[i][j] <= X)并且还没有被访问过(not visited[i][j]),这意味着它是一个新的安全区的起始点。所以,将安全区的数量safe_zone_count加1,并且调用dfs函数来标记这个安全区内的所有格子。 - 最后,函数返回安全区的数量
safe_zone_count。
- 在主逻辑中,首先创建了一个与二维数组 大小相同的布尔型二维数组