10×10方格矩阵中跨侧连通路径识别的代码实现咨询
10×10网格跨侧连通路径识别的通用实现思路
嘿,针对你这个需求,我整理了两个工程里常用的通用实现方案,你可以根据自己的代码场景来选:
先啰嗦几个关键前提,这是后续实现的基础:
- 先敲定连通规则:是四连通(只认上下左右相邻)还是八连通(包含对角线相邻)?这个得先在代码里固定好,比如大部分场景用四连通就够了。
- 明确跨侧定义:水平跨侧是「最左列至少一个橙色块」连通到「最右列至少一个橙色块」;垂直跨侧是「最顶行至少一个橙色块」连通到「最底行至少一个橙色块」。
方案1:BFS/DFS 直观路径搜索
这是最容易上手实现的方案,核心就是从一侧的橙色块出发,搜有没有通路到另一侧。
水平跨侧判断步骤
- 先把最左列(索引0)的所有橙色块坐标捞出来,作为搜索的起点队列/栈。
- 对每个起点做BFS或者DFS:
- 遍历当前块的所有符合连通规则的相邻橙色块,标记成已访问(别绕圈)。
- 要是搜着搜着碰到了最右列(索引9)的橙色块,直接返回「有水平连通路径」。
- 所有起点都搜完还没找到,就说明没有水平连通。
垂直跨侧判断步骤
和水平逻辑一模一样,只是起点换成最顶行(索引0)的橙色块,目标是找最底行(索引9)的橙色块。
伪代码参考(Python风格)
def has_cross_path(grid, direction): rows, cols = 10, 10 visited = set() start_nodes = [] # 确定起点集合和目标条件 if direction == "horizontal": # 最左列的橙色块作为起点 for r in range(rows): if grid[r][0] == "orange": start_nodes.append((r, 0)) # 目标是到达最右列 def is_target(r, c): return c == 9 else: # vertical # 最顶行的橙色块作为起点 for c in range(cols): if grid[0][c] == "orange": start_nodes.append((0, c)) # 目标是到达最底行 def is_target(r, c): return r == 9 # BFS实现(换成DFS也只是把队列改成栈就行) from collections import deque q = deque(start_nodes) for node in start_nodes: visited.add(node) # 四连通方向,要是用八连通就把对角线加上 directions = [(-1,0), (1,0), (0,-1), (0,1)] while q: r, c = q.popleft() # 检查是不是到目标侧了 if is_target(r, c): return True # 遍历所有相邻块 for dr, dc in directions: nr, nc = r + dr, c + dc # 先判断有没有越界,再看是不是橙色且没访问过 if 0 <= nr < rows and 0 <= nc < cols: if grid[nr][nc] == "orange" and (nr, nc) not in visited: visited.add((nr, nc)) q.append((nr, nc)) # 搜完所有可能都没找到 return False # 调用示例 has_horizontal = has_cross_path(your_grid, "horizontal") has_vertical = has_cross_path(your_grid, "vertical") has_cross = has_horizontal or has_vertical
方案2:并查集(Union-Find) 高效动态判断
如果你的网格需要频繁修改(比如动态加/删橙色块),这个方案的效率会比每次重新搜高很多,核心是用集合来管理连通的块。
实现步骤
初始化并查集:给每个橙色块分配唯一ID(比如用
r*10 + c),再额外搞两个虚拟节点:- 水平方向:
LEFT(代表最左列所有橙色块的公共父节点)、RIGHT(代表最右列所有橙色块的公共父节点) - 垂直方向:
TOP(代表最顶行所有橙色块的公共父节点)、BOTTOM(代表最底行所有橙色块的公共父节点)
- 水平方向:
遍历所有橙色块:
- 如果当前块在最左列,把它和
LEFT合并;在最右列就和RIGHT合并(垂直方向同理)。 - 遍历当前块的相邻橙色块,把它们和当前块合并到同一个集合里。
- 如果当前块在最左列,把它和
最后判断:看看
LEFT和RIGHT是不是在同一个集合里(水平连通);TOP和BOTTOM是不是在同一个集合里(垂直连通)。
优势
- 合并和查询操作都是近似O(1)的时间复杂度,适合需要反复判断连通性的场景,比每次跑BFS/DFS省时间。
额外提醒
- 边界别越界:遍历相邻块的时候,一定要判断新坐标是不是在0-9的范围内,不然会出索引错误。
- 连通规则灵活改:要是用八连通,只要把方向列表里加上四个对角线方向
(-1,-1), (-1,1), (1,-1), (1,1)就行。 - 已访问标记不能忘:BFS/DFS里一定要标记已访问的块,不然会无限循环遍历同一个节点。
内容的提问来源于stack exchange,提问作者Jonathan Økland Torstensen




