[AIGC] 宽度优先搜索(BFS) 讲解以及在 LeetCode 题中的应用

宽度优先搜索(Breadth-First Search,简称 BFS)是一种用于图或树结构的遍历算法。它以广度方向进行搜索,首先访问根节点,然后访问所有相邻的节点,然后再通过它们的邻居一直进行下去,直到所有的节点都被访问过。


BFS 的工作过程

BFS 从图的某一节点(称为“源”节点)开始,访问可能的所有顶点,并采取先来先服务的原则。 按照这个算法的一般操作步骤,首先创建一个队列,然后将源节点入队。然后,在图遍历过程中,当队列不为空时,从队列的头部出队一个节点,并将它的所有未访问过的邻居入队。一旦节点被标记为 “已访问”,则表示该节点已经完成了遍历。

BFS 在 LeetCode 中的应用

我们来看一看在 LeetCode 上的题编号 127,题目《单词接龙》。

题目大致为:给定两个单词(beginWord和endWord)和一个字典 wordList ,找出所有从 beginWord 到 endWord 的最短转换序列,转换需遵循如下规则:
每次转换只能改变一个字母,转换过程中的中间单词必须是字典中的单词。

这是一个标准的 BFS 问题,适合应用 BFS 来寻找字典中单词的最短转化路径。

这是该问题的 Python 代码实现:

from collections import defaultdict, deque
class Solution:
    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
        if endWord not in wordList: return 0
        l = len(beginWord)
        ws = defaultdict(list)
        for word in wordList:
            for i in range(l):
                ws[word[:i]+'*'+word[i+1:]].append(word)

        déf bfs(q: deque, v: dict) -> int:
            s, d = q.popleft()
            for i in range(l):
                nw = s[:i] + '*' + s[i+1:]
                for word in ws[nw]:
                    if word == endWord: return d+1
                    if word not in v:
                        v[word] = True
                        q.append((word, d+1))
            return 0
        qq, qe,v1, v2, flg  = deque(), deque(), {}, {}, 0
        qq.append((beginWord, 1))
        v1[beginWord] = True
        return bfs(qq, v1)

在以上代码中,定义了双向宽度优先搜索 (bidirectional breadth-first search) 的框架,遍历的过程后都加入遍历的节点到队列,这样直到找到终止点位置或者结束遍历。对于队列中每个节点,都找他的下一个位置,将其加入到队列中,这样就实现了 BFS 遍历。此问题的求解就是找出从起始点到终止点的最短路径,也就是 BFS 中第一次找到的路径就是最短的路径。

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
重排九宫问题是一种经典的数学难题,也是一种常见的人工智能问题。解决这个问题可以使用宽度优先搜索算法。下面我将介绍如何使用宽度优先搜索算法解决重排九宫问题。 首先,我们将一个 3x3 的棋盘视为一个状态空间,其中每个状态都代表了一个不同的棋局状态。我们的目标是找到一种移动步骤,将当前的棋局状态转换为目标状态。在这个问题中,我们将目标状态设置为如下图所示的状态: ``` 1 2 3 4 5 6 7 8 0 ``` 其中数字 0 代表空格,可以在移动时用于交换两个数的位置。现在我们的任务是找到一种最短的移动步骤,将当前状态转换为目标状态。 接下来,我们将使用宽度优先搜索算法来解决这个问题。我们需要遵循以下步骤: 1. 将当前状态加入队列中,并将其设置为已访问状态。 2. 从队列中取出第一个状态,检查它是否等于目标状态,如果是,则返回移动步骤。 3. 如果不是,我们将生成所有可能的下一步状态,并检查它们是否已经被访问过。如果没有被访问过,则将其加入队列中,并将其设置为已访问状态。 4. 重复步骤 2 和 3,直到找到目标状态或队列为空。 下面是使用 Python 实现宽度优先搜索算法解决重排九宫问题的示例代码: ```python from collections import deque # 目标状态 goal_state = [[1, 2, 3], [4, 5, 6], [7, 8, 0]] # 移动操作 moves = { "up": (-1, 0), "down": (1, 0), "left": (0, -1), "right": (0, 1), } def bfs(start_state): # 初始化队列和已访问状态 queue = deque([(start_state, "", 0)]) visited = set([tuple(map(tuple, start_state))]) # 开始搜索 while queue: state, path, steps = queue.popleft() # 检查是否达到目标状态 if state == goal_state: return path # 生成下一步状态 for move, (dx, dy) in moves.items(): new_state = [row[:] for row in state] x, y = find_zero(state) nx, ny = x + dx, y + dy if 0 <= nx < 3 and 0 <= ny < 3: new_state[x][y], new_state[nx][ny] = new_state[nx][ny], new_state[x][y] if tuple(map(tuple, new_state)) not in visited: queue.append((new_state, path + move, steps + 1)) visited.add(tuple(map(tuple, new_state))) # 无解情况 return "No solution found" def find_zero(state): for i in range(3): for j in range(3): if state[i][j] == 0: return i, j # 测试代码 start_state = [[2, 3, 6], [1, 5, 0], [7, 8, 4]] print(bfs(start_state)) ``` 在上面的代码中,我们使用了 Python 中的 deque 和 set 数据结构来实现队列和已访问状态的功能。我们还定义了一个字典 moves,用于存储每个移动操作对应的行列偏移量。函数 find_zero 用于查找空格的位置。最后,我们使用测试数据调用函数 bfs,并打印出移动步骤。 这就是使用宽度优先搜索算法求解重排九宫问题的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员三木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值