迷宫中给定两个节点时如何查找最近交汇节点?算法选型与BFS应用疑问
如何找到源节点和目标节点的最近交汇节点
首先,我们先明确问题的核心:交汇节点是指同时被源节点(src)和目标节点(dest)正向可达的节点,而"最近"是指该节点到src的距离加上到dest的距离之和最小。结合你提到的迷宫特性(每个节点出口不超过1个,即正向图中每个节点出度≤1),我们可以用更高效的方法解决这个问题,而不仅仅是BFS。
一、用双向BFS找到最近交汇节点的正确姿势
你已经分别做了src和dest的BFS,但可能没意识到如何利用这两个遍历的结果来定位最近节点。这里的关键是跟踪每个节点从src和dest出发的距离,然后找到距离和最小的共同节点:
步骤1:计算每个节点到src的距离
因为每个节点出度唯一,你甚至不需要完整的BFS,直接遍历src的正向路径即可:
- 从src开始,沿着
nodes数组的指向一步步走,记录每个节点的距离(src自身距离为0,下一个节点距离为1,以此类推),直到走到-1或进入环(避免无限循环)。 - 把这些节点和距离存入一个哈希表(比如
srcDist)。
步骤2:计算每个节点到dest的距离并找交汇点
同样遍历dest的正向路径:
- 每走到一个节点,检查它是否在
srcDist中。 - 如果存在,计算
当前dest距离 + srcDist.get(node),记录这个总和最小的节点。
以你的例子来说:
- src=9的路径是
9→8→0→4→13→11→9,对应的距离是9:0, 8:1, 0:2, 4:3, 13:4, 11:5。 - dest=2的路径是
2→1→4→13→11→9→8→0,对应的距离是2:0, 1:1, 4:2, 13:3, 11:4, 9:5, 8:6, 0:7。 - 当遍历到4时,发现它在
srcDist中,总和是3+2=5;后续遍历到13时总和是4+3=7,9的总和是0+5=5。这里总和最小的是4和9,但因为4是dest路径中第一个遇到的共同节点(且总和相同的情况下通常优先选离dest更近的),所以答案是4。
如果你想用双向BFS优化:
- 同时从src和dest出发,每次各扩展一步(或一层),记录两个方向访问过的节点和距离。
- 每次扩展后,检查当前节点是否在对方的访问集合中。一旦找到,计算总距离,因为BFS是按距离从小到大扩展的,第一个找到的总距离最小的节点就是答案(比如你的例子中,src扩展到4时,dest已经访问过4,此时总距离5是最小的,直接返回即可)。
二、除了BFS,还有哪些适用算法?
由于你的迷宫是功能图(每个节点出度≤1),有几个更贴合场景的算法:
1. 路径遍历+哈希集合
这是最直观的方法,因为每个节点的路径是唯一的:
- 先遍历src的路径,把所有节点存入集合并记录距离。
- 再遍历dest的路径,逐个检查节点是否在集合中,计算总距离并保留最小值。
- 优点:实现简单,时间复杂度O(n)(n是路径长度),适合这种单出口的迷宫。
2. 标记法
- 第一次遍历src的路径,给每个节点打上标记(比如用一个布尔数组
visited),同时记录距离。 - 第二次遍历dest的路径,遇到第一个被标记的节点时,计算总距离;继续遍历,记录所有标记节点的总距离,取最小的那个。
3. Floyd判圈算法(针对含环的场景)
如果路径中存在环(比如你的例子中src的路径是环),可以用快慢指针先找到src路径的环,再检查dest的路径是否进入这个环,找到第一个进入环的节点,这个节点就是交汇点之一,再计算总距离即可。
总结
对于这种单出口的迷宫,最高效的方法是直接遍历两个节点的路径,用哈希集合或标记法找共同节点并计算最小距离和。双向BFS也适用,但针对单出口的特性,路径遍历的实现会更简单直接。
内容的提问来源于stack exchange,提问作者Aditya Dixit
相关产品推荐
相关产品推荐

