问题描述
小F被神秘力量带入了一个魔幻世界,这里危机四伏。为了在异世界中生存,小F需要找到安全区。异世界可以被表示为一个大小为 n x m
的二维数组,每个格子的值代表该位置的危险程度。
小F的能力值为 X
,当某个格子的危险程度小于等于 X
时,这个格子是安全的。如果多个安全的格子相邻(上下左右连通),它们可以构成一个安全区。你需要帮助小F计算出一共有多少个安全区。
问题理解
需要在一个 n x m
的二维数组中找到所有安全区的数量。安全区的定义是:所有相邻的格子(上下左右)的危险程度都小于等于 X
。
数据结构选择
- 二维数组:用于存储每个格子的危险程度。
- 访问标记数组:用于标记哪些格子已经被访问过,避免重复计算。
算法步骤
- 初始化:创建一个与输入数组相同大小的访问标记数组,初始值为
False
,表示所有格子都未被访问。 - 遍历数组:对于每个格子,如果该格子未被访问且危险程度小于等于
X
,则从这个格子开始进行深度优先搜索(DFS)或广度优先搜索(BFS),找到所有与之相邻的安全格子,并将它们标记为已访问。 - 计数:每完成一次搜索,安全区的数量加一。
- 返回结果:遍历结束后,返回安全区的数量。
具体步骤
- DFS/BFS函数:编写一个递归的DFS函数或使用队列的BFS函数,用于从某个未访问的安全格子开始,访问所有与之相邻的安全格子。
- 主函数:遍历整个二维数组,调用DFS/BFS函数,并统计安全区的数量。
代码实现
def solution(n: int, m: int, X: int, a: list[list[int]]) -> int:
visited = [[False] * m for _ in range(n)]
def dfs(i, j):
if i < 0 or i >= n or j < 0 or j >= m or visited[i][j] or a[i][j] > X:
return
visited[i][j] = True
dfs(i + 1, j) # 下
dfs(i - 1, j) # 上
dfs(i, j + 1) # 右
dfs(i, j - 1) # 左
safe_zones = 0
for i in range(n):
for j in range(m):
if not visited[i][j] and a[i][j] <= X:
dfs(i, j)
safe_zones += 1
return safe_zones
时间复杂度
- 遍历二维数组:在主函数中,我们遍历了整个
n x m
的二维数组。这一步的时间复杂度是O(n * m)
。 - DFS函数调用:对于每个未访问且危险程度小于等于
X
的格子,我们调用一次DFS函数。在最坏情况下,每个格子都会被访问一次,因此DFS函数的时间复杂度也是O(n * m)
。
综合来看,整个算法的时间复杂度是 O(n * m)
。
空间复杂度
- 访问标记数组:我们创建了一个与输入数组相同大小的访问标记数组
visited
,其空间复杂度是O(n * m)
。 - 递归栈空间:在DFS函数中,递归调用会占用栈空间。在最坏情况下,递归深度可以达到
n * m
,因此递归栈的空间复杂度也是O(n * m)
。
综合来看,整个算法的空间复杂度是 O(n * m)
。
总结
- 时间复杂度:
O(n * m)
- 空间复杂度:
O(n * m)