美文网首页
算法学习:双向BFS

算法学习:双向BFS

作者: alex很累 | 来源:发表于2023-11-04 13:34 被阅读0次

理论

解决的问题

在朴素的 BFS 实现中,空间的瓶颈主要取决于搜索空间中的最大宽度。

解决的方法

同时从两个方向开始搜索,一旦搜索到相同的值,意味着找到了一条联通起点和终点的最短路径。


实现的基本思路
  1. 创建「两个队列」分别用于两个方向的搜索;
  2. 创建「两个哈希表」用于表示「访问过的节点」;
  3. 为了尽可能让两个搜索方向“平均”,每次从队列中取值进行扩展时,先判断哪个队列容量较少,队列数据较少的先执行;
  4. 如果在搜索过程中「搜索到对方搜索过的节点」,说明找到了最短路径;如果结束搜索过程后,还没有找到,表示不连通。

算法实践

127. 单词接龙

问题描述

字典 wordList 中从单词 beginWordendWord转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk
每一对相邻的单词只差一个字母。
对于 1 <= i <= k 时,每个 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中。
sk == endWord
给你两个单词 beginWordendWord 和一个字典 wordList ,返回 从 beginWordendWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0

示例
输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出:5
解释:一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。

输入:beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
输出:0
解释:endWord "cog" 不在字典中,所以无法进行转换。
解题思路
  1. 先判断endWord是否在wordList中,如果不在,直接返回0
  2. 创建两个队列分别表示2个方向的搜索;
  3. 对两个队列进行bfs,优先跑队列长度小的队列;
  4. 当搜索过程中「搜索到对方搜索过的节点」,返回搜索次数。
代码示例(JAVA)
class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        Set<String> wordSet = new HashSet<>();
        for (String word : wordList) {
            wordSet.add(word);
        }
        if (!wordList.contains(endWord)) {
            return 0;
        }

        Set<String> startSet = new HashSet<>();
        Set<String> endSet = new HashSet<>();
        Set<String> visited = new HashSet<>();
        startSet.add(beginWord);
        endSet.add(endWord);

        int len = 1;
        while (!startSet.isEmpty() && !endSet.isEmpty()) {
            // 优先跑少的部分
            if (startSet.size() > endSet.size()) {
                Set<String> temp = startSet;
                startSet = endSet;
                endSet = temp;
            }

            Set<String> temp = new HashSet<>();
            for (String word : startSet) {
                char[] chars = word.toCharArray();
                for (int i = 0; i < chars.length; i++) {
                    char old = chars[i];
                    for (char k = 'a'; k <= 'z'; k++) {
                        if (chars[i] == k) {
                            continue;
                        }
                        chars[i] = k;
                        String newString = String.valueOf(chars);
                        if (endSet.contains(newString)) {
                            return len + 1;
                        }
                        if (!visited.contains(newString) && wordSet.contains(newString)) {
                            temp.add(newString);
                            visited.add(newString);
                        }
                        chars[i] = old;
                    }
                }
            }
            startSet = temp;
            len++;
        }
        return 0;
    }
}
类似的题目

433. 最小基因变化

相关文章

  • 双向BFS

    双向BFS适用于目标节点已知的情况;初始结点向目标结点和目标结点向初始结点同时扩展,直至在两个扩展方向上出现同一个...

  • 走迷宫(BFS例题)

    BFS例题---走迷宫 BFS对应数据结构queue BFS算法时间复杂度O(n^2) BFS算法不走走过的点 的...

  • 图论小结

    图的存储 邻接矩阵 邻接表 图的遍历 DFS(双向DFS) BFS(剪枝) 单源最短路径算法 dij 条件:无负权...

  • G - 7 UVA - 11624

    所用算法:BFS

  • H - 8 POJ - 3984

    所用算法:BFS

  • ORID27

    [127] Word Ladder解题报告 BFS算法 用什么算法?这道题需要用 BFS为什么用这个算法(那些条件...

  • LeetCode 第207题:课程表

    1、前言 2、思路 使用拓扑排序的方法,拓扑排序其实是使用的 BFS 算法,简而言之使用 BFS 算法解题。算法流...

  • BFS

    [TOC] BFS 和 DFS BFS广度有限搜索和DFS深度优先搜索算法是特别常用的两种算法 DFS 算法就是回...

  • LeetCode127. 单词接龙

    语言:Java算法:BFS AC代码:

  • 算法与数据结构 之 搜索算法

    搜索分为广度优先搜索、深度优先搜索、A*算法。 一、广度优先算法(BFS) 1.1、基本实现和特性:BFS是从一个...

网友评论

      本文标题:算法学习:双向BFS

      本文链接:https://www.haomeiwen.com/subject/vbyaidtx.html