美文网首页
算法学习:双向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

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