技术问题:扇区单元格计数——查找网格内最大填充连通区域
如何找出二维网格中最大的8连通扇区?
首先明确问题:我们有一个由0和1组成的二维网格,其中1代表已填充单元格,0代表空单元格。8方向连通(水平、垂直、对角相邻)的1会构成一个扇区,我们需要找出所有扇区中单元格数量最多的那个的大小。
这本质上是经典的连通分量查找问题,最常用的解法是深度优先搜索(DFS)或者广度优先搜索(BFS),下面我会分别给出两种实现方案,并解释关键细节。
方法一:深度优先搜索(DFS)
DFS的思路是:遍历网格中的每个单元格,当遇到未访问过的1时,递归遍历它所有8方向的相邻单元格,统计这个扇区的总大小,同时标记已访问的单元格避免重复计算。
代码实现(Python)
def largest_sector(grid): # 处理空网格的边界情况 if not grid or not grid[0]: return 0 rows, cols = len(grid), len(grid[0]) max_sector_size = 0 # 定义8个方向的偏移量(上、下、左、右、四个对角) directions = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] def dfs(row, col): # 越界或者当前单元格不是1,直接返回0 if row < 0 or row >= rows or col < 0 or col >= cols or grid[row][col] != 1: return 0 # 标记为已访问:把当前1改成0,避免再次遍历 grid[row][col] = 0 sector_size = 1 # 遍历所有8个方向,累加连通的单元格数量 for dr, dc in directions: sector_size += dfs(row + dr, col + dc) return sector_size # 遍历网格中的每个单元格 for r in range(rows): for c in range(cols): if grid[r][c] == 1: current_size = dfs(r, c) # 更新最大扇区大小 if current_size > max_sector_size: max_sector_size = current_size return max_sector_size
关键细节说明
- 我们直接修改原网格来标记已访问的单元格(把1改成0),这样不需要额外的空间存储访问状态;如果不想破坏原网格,可以单独创建一个和网格大小一致的
visited布尔矩阵,访问过的单元格设为True。 - DFS是递归实现,当网格非常大(比如整个网格都是1)时,可能会遇到递归栈溢出的问题,这时候可以改用迭代版DFS或者BFS。
方法二:广度优先搜索(BFS)
BFS用队列来实现迭代遍历,避免了递归栈溢出的问题,思路和DFS类似:遇到未访问的1时,将其加入队列,然后依次处理队列中的每个单元格,遍历其8方向的相邻单元格,统计扇区大小。
代码实现(Python)
from collections import deque def largest_sector_bfs(grid): if not grid or not grid[0]: return 0 rows, cols = len(grid), len(grid[0]) max_sector_size = 0 directions = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] for r in range(rows): for c in range(cols): if grid[r][c] == 1: # 初始化队列,加入当前单元格 queue = deque() queue.append((r, c)) grid[r][c] = 0 current_size = 0 # 处理队列中的所有单元格 while queue: curr_row, curr_col = queue.popleft() current_size += 1 # 遍历8个方向 for dr, dc in directions: new_row, new_col = curr_row + dr, curr_col + dc # 检查新单元格是否合法且未被访问 if 0 <= new_row < rows and 0 <= new_col < cols and grid[new_row][new_col] == 1: grid[new_row][new_col] = 0 queue.append((new_row, new_col)) # 更新最大扇区大小 max_sector_size = max(max_sector_size, current_size) return max_sector_size
复杂度分析
- 时间复杂度:O(M*N),其中M是网格行数,N是列数。每个单元格最多被访问一次,所以总时间和网格大小成正比。
- 空间复杂度:最坏情况下是O(M*N),比如整个网格都是1时,DFS的递归栈或者BFS的队列都会占用和网格大小相当的空间。
内容的提问来源于stack exchange,提问作者user9716844
相关产品推荐
相关产品推荐

