BFS解题模板
首先明确BFS的核心思想,就是将问题抽象成一个图,从一个点开始向四周扩散,所以我们会使用QUeue这种核心数据结构,BFS常用于寻找最短路径问题,相比于DFS时间复杂度更低,因为DFS总要走到底然后才能得出这条路有多长,然后在进行对比,当然BFS也有弊端,空间复杂度很高,当我们要寻找的目标在最深处时,那么我们将会遍历到所有的节点,空间的消耗是比较大的。
所以接下来的代码是一个比较标准的解题模板,细心品味
1 | // 计算从起点 start 到终点 target 的最近距离 |
下面用一个leetCode的例题来找出解题思路:
你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’ 。每个拨轮可以自由旋转:例如把 ‘9’ 变为 ‘0’,’0’ 变为 ‘9’ 。每次旋转都只能旋转一个拨轮的一位数字。
锁的初始数字为 ‘0000’ ,一个代表四个拨轮的数字的字符串。
列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。
字符串 target 代表可以解锁的数字,你需要给出最小的旋转次数,如果无论如何不能解锁,返回 -1。
解题思路:
其实这是关于解密码的问题,当我们旋转一次每个位置可以向上向下两种方案,所以可以看作每个节点都有8个相邻节点,穷举出所有的组合方式,在使用BFS搜索方式可以找出最短路径。
下面的方法是实现向上和向下两种旋转方案:
1 | /** |
接下来实现主方法,我们可以将deads和visited放入到Set集合中,这样我们可以方便判断包含关系,并且它们的特性也刚好是不重复的
1 | public int openLock(String[] deadends, String target) { |
在对比以下标准模板我们不难发现只是添加了一些对细节的要求,但接下来会介绍更高效的一种方法,双向BFS,这种解题方法我们有一个前提,就是必须要知道我们要寻找的终点,然后从两端开始向BFS,直到有交集时结束,例如本体target就是终点,所以我们可以采取这种方法来解题
1 | int openLock(String[] deadends, String target) { |
作者:labuladong
链接:https://leetcode-cn.com/problems/open-the-lock/solution/wo-xie-liao-yi-tao-bfs-suan-fa-kuang-jia-jian-dao-/
来源:力扣(LeetCode)