第309题-题目解析 | 豆包MarsCode AI刷题;

31 阅读4分钟

309-魔幻世界中的安全区计算

问题描述

小F被神秘力量带入了一个魔幻世界,这里危机四伏。为了在异世界中生存,小F需要找到安全区。异世界可以被表示为一个大小为 n x m 的二维数组,每个格子的值代表该位置的危险程度。

小F的能力值为 X,当某个格子的危险程度小于等于 X 时,这个格子是安全的。如果多个安全的格子相邻(上下左右连通),它们可以构成一个安全区。你需要帮助小F计算出一共有多少个安全区。

以下是根据题目要求编写代码的思路以及对应的代码实现:

一、整体思路

  1. 数据表示与初始化

    • 我们需要处理一个大小为 n×mn\times m 的二维数组来表示异世界。首先要考虑如何表示这个二维数组以及相关的变量,如小F的能力值 XX
    • 我们可以定义一个函数,接受 nnmmXX 和表示异世界危险程度的二维数组作为参数。
  2. 安全区的判定与搜索

    • 对于每个格子,需要判断它是否是安全的(即危险程度小于等于 XX)。如果是安全的且未被标记过,那么它可能是一个新的安全区的起点。
    • 采用深度优先搜索(DFS)或者广度优先搜索(BFS)来标记属于同一个安全区的所有格子。这里以DFS为例,从一个安全格子开始,递归地访问它的上下左右相邻格子,如果相邻格子也是安全的且未被访问过,就继续递归访问这个相邻格子,直到没有更多的相邻安全格子为止。
  3. 安全区数量的统计

    • 在遍历二维数组的过程中,每发现一个新的未被访问的安全格子并完成对其所在安全区的标记,就将安全区的数量加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

三、代码解析

  1. dfs函数

    • 这是一个递归函数,用于深度优先搜索。它的目的是标记从给定坐标 (x,y)(x,y) 开始的同一个安全区内的所有格子。
    • 首先,它进行边界检查,确保坐标 (x,y)(x,y) 在二维数组的合法范围内,并且该格子的危险程度小于等于 XX,同时这个格子还没有被访问过。如果满足这些条件,就将这个格子标记为已访问(visited[x][y]=True)。
    • 然后,它递归地调用自身来访问这个格子的上下左右相邻格子。例如,dfs(x - 1,y) 会访问当前格子上方的格子(假设坐标系统中,上方格子的 xx 坐标比当前格子小1)。这种递归调用会持续进行,直到没有更多符合条件的相邻格子为止。
  2. 主逻辑部分

    • 在主逻辑中,首先创建了一个与二维数组 aa 大小相同的布尔型二维数组 visited,用于标记每个格子是否被访问过。初始时,所有元素都为 False
    • 然后,使用两层嵌套的循环遍历二维数组 aa。对于每个格子,如果它是安全的(a[i][j] <= X)并且还没有被访问过(not visited[i][j]),这意味着它是一个新的安全区的起始点。所以,将安全区的数量 safe_zone_count 加1,并且调用 dfs 函数来标记这个安全区内的所有格子。
    • 最后,函数返回安全区的数量 safe_zone_count