leetcode 126. 单词接龙 II(回溯记录路径)

使用双向BFS解决单词接龙问题,记录最短路径。在每层BFS开始前标记节点,避免环形结构影响效率。回溯过程中根据遍历方向构建路径。
摘要由CSDN通过智能技术生成

题目描述

按字典 wordList 完成从单词 beginWord 到单词 endWord 转化,一个表示此过程的 转换序列 是形式上像 beginWord -> s1 -> s2 -> … -> sk 这样的单词序列,并满足:

  • 每对相邻的单词之间仅有单个字母不同。
  • 转换过程中的每个单词 si(1 <= i <= k)必须是字典 wordList 中的单词。注意,beginWord 不必是字典 wordList 中的单词。
  • sk == endWord

给你两个单词 beginWordendWord ,以及一个字典 wordList 。请你找出并返回所有从 beginWordendWord 的 最短转换序列,如果不存在这样的转换序列,返回一个空列表。每个序列都应该以单词列表 [beginWord, s1, s2, …, sk] 的形式返回。

示例 1:

输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”,“cog”]
输出:[[“hit”,“hot”,“dot”,“dog”,“cog”],[“hit”,“hot”,“lot”,“log”,“cog”]]
解释:存在 2 种最短的转换序列:
“hit” -> “hot” -> “dot” -> “dog” -> “cog”
“hit” -> “hot” -> “lot” -> “log” -> “cog”

示例 2:

输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”]
输出:[]
解释:endWord “cog” 不在字典 wordList 中,所以不存在符合要求的转换序列。

提示:

  • 1 <= beginWord.length <= 7
  • endWord.length == beginWord.length
  • 1 <= wordList.length <= 1000
  • wordList[i].length == beginWord.length
  • beginWord、endWord 和 wordList[i] 由小写英文字母组成
  • beginWord != endWord
  • wordList 中的所有单词 互不相同

题目分析

在这里插入图片描述
该题目的简单类型在上篇文章 leetcode 127. 单词接龙 中进行了详细的分析,要看详细的分析请看上篇分析。那么这篇文章在上篇文章的基础上进行了修改,并添加了记录路径的方法。

解题方案
(1)同样使用双向BFS的方法,每次从队列长度小的一端开始搜索。(2)在对某一层BFS开始之前,先将队列中的全部元素进行标记(至于为什么这么做,后边会解释)。(3)然后开始BFS,如果遍历到的节点未被标记,那么将该节点放入队列中,如果该节点存在于另一个队列中,说明已经找到最短的路径了。(4)此时将该层节点遍历结束后,方可进行回溯记录路径。(5)此外,需要在遍历节点的时候,通过判断这次遍历是从后向前还是从前向后,以确定构建的图的起始节点和结束节点。

(2)在对某一层BFS开始之前,先将队列中的全部元素进行标记。
在这里插入图片描述
假设遍历到了上图标记的位置,此时队列中的元素为 [ dot, lot] ,再次向后遍历的话,因为 doghot 都与 dot 相连,那么这两个元素都会入队列,可 hot 入队之后,程序的运行就会产生一个环形结构,这会对程序运行效率是极其不友好的,像这种情况,我们希望的是只将 dog 入队。因此,在程序开始之处,通过 wordList 构建一个wordListSet集合,集合中是全部未遍历过的元素。当队列中的元素是橘黄色指针指向的位置的时候,先将队列中的全部元素从wordListSet中删除(表示上一层的元素全部访问过),然后再遍历后边一层的元素(即:doglog)后边一层中,只有存在于wordListSet中的元素才能入队。

(5)回溯建图
在这里插入图片描述
如上图所示,假设遍历到了箭头指向的位置(将hot从队列中弹出,并将[dot, lot]放入队列中),如果我们从正方向遍历的时候,map<key, val>中的 key 就是 hot , val 就是[dot, lot],即 map<hot, [dot, lot]>
在这里插入图片描述
如上图所示,假设遍历到了箭头指向的位置(将log从队列中弹出并将lot放入队列中),如果从反方向遍历的时候,map<key, val>中的 key 就是 lot , val 就是 log,即 map<lot, log>

代码

public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
   

        wordList.add(beginWord);

        // 构建一个标记集合,开始的时候,每个word都在集合中。后边每次将元素放到队列中,便将该元素从集合中删除,以实现标记功能
        Set<String> wordListSet = new HashSet
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Zhang L.R.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值