难度: Medium
Submission
运行时间: 1051 ms
内存: 25.8 MB
class Solution: def largestArea(self, grid: List[str]) -> int: m = len(grid) n = len(grid[0]) info = [[0] * n for i in range(m)] opts = [] tmp_opts = None for j in range(n): opts.append((0, j)) info[0][j] = 1 opts.append((m - 1, j)) info[m - 1][j] = 1 for i in range(1, m - 1): opts.append((i, 0)) info[i][0] = 1 opts.append((i, n - 1)) info[i][n - 1] = 1 for j in range(1, n - 1): if grid[i][j] == '0': opts.append((i, j)) info[i][j] = 1 # print(opts) while opts: tmp_opts = [] for x, y in opts: r, c = x - 1, y if r >= 0 and (grid[x][y] == '0' or grid[r][c] == grid[x][y]) and info[r][c] == 0: tmp_opts.append((r, c)) info[r][c] = 1 r, c = x + 1, y # if r == 1 and c == 1: # print(x, y, grid[x][y], grid[x][y] == 0, grid[x][y] == '0') if r < m and (grid[x][y] == '0' or grid[r][c] == grid[x][y]) and info[r][c] == 0: tmp_opts.append((r, c)) info[r][c] = 1 r, c = x, y - 1 if c >= 0 and (grid[x][y] == '0' or grid[r][c] == grid[x][y]) and info[r][c] == 0: tmp_opts.append((r, c)) info[r][c] = 1 r, c = x, y + 1 if c < n and (grid[x][y] == '0' or grid[r][c] == grid[x][y]) and info[r][c] == 0: tmp_opts.append((r, c)) info[r][c] = 1 opts = tmp_opts # print(opts) # print(info) res = 0 for i in range(1, m - 1): for j in range(1, n - 1): if info[i][j] > 0: continue tmp = 1 opts = [(i, j)] info[i][j] = 1 while opts: tmp_opts = [] for x, y in opts: r, c = x - 1, y if grid[r][c] == grid[x][y] and info[r][c] == 0: tmp_opts.append((r, c)) info[r][c] = 1 tmp += 1 r, c = x + 1, y if grid[r][c] == grid[x][y] and info[r][c] == 0: tmp_opts.append((r, c)) info[r][c] = 1 tmp += 1 r, c = x, y - 1 if grid[r][c] == grid[x][y] and info[r][c] == 0: tmp_opts.append((r, c)) info[r][c] = 1 tmp += 1 r, c = x, y + 1 if grid[r][c] == grid[x][y] and info[r][c] == 0: tmp_opts.append((r, c)) info[r][c] = 1 tmp += 1 opts = tmp_opts res = max(res, tmp) return res
Explain
此题解采用了广度优先搜索(BFS)的方法来解决问题。首先,使用一个二维数组info来记录是否访问过每个单元格。初始时,将所有边界单元格以及所有的'0'(走廊)加入到搜索队列opts中,因为它们都与边界接壳。接下来,进行广度优先搜索,将与走廊相连的主题空间的每个部分标记为已访问。这一步确保了所有与走廊相连的区域都被标记。之后,再遍历数组,对于每一个未被访问的非走廊格子,从该位置出发进行广度优先搜索计算该区域的大小,并更新最大面积。最终返回最大的非与走廊相邻的主题空间面积。
时间复杂度: O(m*n)
空间复杂度: O(m*n)
class Solution: def largestArea(self, grid: List[str]) -> int: m = len(grid) n = len(grid[0]) # 创建一个与grid大小相同的标记数组,记录是否访问过 info = [[0] * n for i in range(m)] opts = [] # 队列,用于BFS tmp_opts = None # 初始化队列,包括所有边界单元格和'0'单元格 for j in range(n): opts.append((0, j)) info[0][j] = 1 opts.append((m - 1, j)) info[m - 1][j] = 1 for i in range(1, m - 1): opts.append((i, 0)) info[i][0] = 1 opts.append((i, n - 1)) info[i][n - 1] = 1 for j in range(1, n - 1): if grid[i][j] == '0': opts.append((i, j)) info[i][j] = 1 # 执行BFS以标记所有与走廊相邻的区域 while opts: tmp_opts = [] for x, y in opts: # 检查四个方向 for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]: nx, ny = x + dx, y + dy if 0 <= nx < m and 0 <= ny < n and (grid[x][y] == '0' or grid[nx][ny] == grid[x][y]) and info[nx][ny] == 0: tmp_opts.append((nx, ny)) info[nx][ny] = 1 opts = tmp_opts res = 0 # 计算最大非走廊相邻区域的大小 for i in range(1, m - 1): for j in range(1, n - 1): if info[i][j] == 0: # 未被标记的区域 tmp = 1 opts = [(i, j)] info[i][j] = 1 while opts: tmp_opts = [] for x, y in opts: for dx, dy in [(-1, 0), (1, 0), (0, -1), (0, 1)]: nx, ny = x + dx, y + dy if 0 <= nx < m and 0 <= ny < n and grid[nx][ny] == grid[x][y] and info[nx][ny] == 0: tmp_opts.append((nx, ny)) info[nx][ny] = 1 tmp += 1 opts = tmp_opts res = max(res, tmp) return res
Explore
在广度优先搜索(BFS)中,通过从所有边界单元格以及所有'0'(走廊)单元格开始初始化队列,并标记这些单元格为已访问,确保了搜索的起点覆盖了所有可能与外界直接接触的区域。随后,在BFS过程中,对于队列中的每个单元格,检查其四周的邻接单元格。如果邻接单元格是同类型(即走廊或相同标识的其他单元格)且未被访问过,则将其加入队列并标记为已访问。这个过程递归地标记所有与初始走廊相连的区域。因此,通过逐层扩展这种标记,可以确保所有与走廊相连的区域都被正确地标记为已访问。
在初始化队列时,将所有边界单元格以及边界上的'0'(走廊)单元格加入队列是为了从所有可能与外部直接接触的点开始广度优先搜索。这样做是因为只有这些单元格可能直接或间接与外界接壳,其他非边界的'0'单元格虽然也是走廊,但它们在初始阶段被环绕在内部,不会直接接触到边界。通过从边界开始的BFS过程自然会访问到所有与这些边界走廊相连的内部走廊,因此无需在初始阶段将它们加入队列。这样做可以减少初始队列的大小,提高效率。
虽然走廊可能由多个不连续的部分组成,但通过从所有边界单元格和边界上的'0'(走廊)单元格开始BFS,可以确保这些不连续部分都能被访问。这是因为BFS算法从多个起点(边界单元格和走廊)开始,能够向内部扩展,逐步访问所有与这些起点相连的区域,包括那些内部但与边界走廊直接或间接相连的走廊部分。每当访问一个走廊单元格,就会检查其四周的单元格,如果邻接单元格也是走廊且未被访问,则会被加入到BFS的下一轮迭代中,这样逐步扩展可以覆盖所有连续或不连续的走廊部分。