给定两个单词(beginWord endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:
  1. 每次转换只能改变一个字母。
  2. 转换过程中的中间单词必须是字典中的单词。

说明:

  • 如果不存在这样的转换序列,返回 0。
  • 所有单词具有相同的长度。
  • 所有单词只由小写字母组成。
  • 字典中不存在重复的单词。
  • 你可以假设 beginWordendWord 是非空的,且二者不相同。

示例 1:

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

示例 2:

输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]输出: 0解释: endWord "cog" 不在字典中,所以无法进行转换。

双向广度优先搜索

本题要求的是最短转换序列的长度,看到最短首先想到的就是广度优先搜索。想到广度优先搜索自然而然的就能想到图,但是本题并没有直截了当的给出图的模型,因此我们需要把它抽象成图的模型。

我们可以把每个单词都抽象为一个点,如果两个单词可以只改变一个字母进行转换,那么说明他们之间有一条双向边。因此我们只需要把满足转换条件的点相连,就形成了一张

基于该图,我们以 beginWord 为图的起点,以 endWord 为终点进行广度优先搜索,寻找 beginWordendWord 的最短路径。

根据给定字典构造的图可能会很大,而广度优先搜索的搜索空间大小依赖于每层节点的分支数量。假如每个节点的分支数量相同,搜索空间会随着层数的增长指数级的增加。考虑一个简单的二叉树,每一层都是满二叉树的扩展,节点的数量会以 222 为底数呈指数增长。

如果使用两个同时进行的广搜可以有效地减少搜索空间。一边从 beginWord 开始,另一边从 endWord 开始。我们每次从两边各扩展一层节点,当发现某一时刻两边都访问过同一顶点时就停止搜索。这就是双向广度优先搜索,它可以可观地减少搜索空间大小,从而提高代码运行效率。

Python

class Solution:def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> Union[int, float]:def addWord(word: str):if word not in wordId:nonlocal nodeNumwordId[word] = nodeNumnodeNum += 1def addEdge(word: str):addWord(word)id1 = wordId[word]chars = list(word)for i in range(len(chars)):tmp = chars[i]chars[i] = '*'newWord = ''.join(chars)addWord(newWord)id2 = wordId[newWord]edge[id1].append(id2)edge[id2].append(id1)chars[i] = tmpwordId, nodeNum = dict(), 0edge = collections.defaultdict(list)for word in wordList:addEdge(word)addEdge(beginWord)if endWord not in wordId:return 0disBegin = [float("inf")] * nodeNumbeginId = wordId[beginWord]disBegin[beginId] = 0queBegin = collections.deque([beginId])disEnd = [float("inf")] * nodeNumendId = wordId[endWord]disEnd[endId] = 0queEnd = collections.deque([endId])while queBegin or queEnd:queBeginSize = len(queBegin)for _ in range(queBeginSize):nodeBegin = queBegin.popleft()if disEnd[nodeBegin] != float("inf"):return (disBegin[nodeBegin] + disEnd[nodeBegin]) // 2 + 1for it in edge[nodeBegin]:if disBegin[it] == float("inf"):disBegin[it] = disBegin[nodeBegin] + 1queBegin.append(it)queEndSize = len(queEnd)for _ in range(queEndSize):nodeEnd = queEnd.popleft()if disBegin[nodeEnd] != float("inf"):return (disBegin[nodeEnd] + disEnd[nodeEnd]) // 2 + 1for it in edge[nodeEnd]:if disEnd[it] == float("inf"):disEnd[it] = disEnd[nodeEnd] + 1queEnd.append(it)return 0

127. Word Ladder 单词接龙相关推荐

  1. 【重点BFS】LeetCode 127. Word Ladder

    LeetCode 127. Word Ladder Solution1:我的超过40%的AC的答案 原先利用BFS做但是内存溢出未能AC:进过修改加上了标记是否访问过的visited数组,可以AC啦~ ...

  2. LeetCode 127. Word Ladder

    原题链接在这里:https://leetcode.com/problems/word-ladder/ 题目: Given two words (beginWord and endWord), and ...

  3. 127. Word Ladder

    文章目录 1 题目理解 2 BFS 3 双向BFS 1 题目理解 给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度 ...

  4. 【LeetCode】127. Word Ladder 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/word-lad ...

  5. [LeetCode#127]Word Ladder

    ---恢复内容开始--- The problem: Given two words (start and end), and a dictionary, find the length of shor ...

  6. 127.Word Ladder

    class Solution { public:int ladderLength(string start, string end, unordered_set<string> & ...

  7. Leetcode每日一题:127.word-ladder(单词接龙)

    思路:树的层次遍历,BFS,注意这里如果用bool数组标记该字符串是否加入过序列,肯定会超时,因为每次都要遍历整个wordList,所以,建议将加入序列的字符串从wordList中删除,勉强过关:DF ...

  8. 算法细节系列(20):Word Ladder系列

    算法细节系列(20):Word Ladder系列 详细代码可以fork下Github上leetcode项目,不定期更新. 题目摘自leetcode: 1. Leetcode 127: Word Lad ...

  9. Word Ladder

    LeetCode[127. Word Ladder] 题解 难度[medium] 题目: Given two words (beginWord and endWord), and a dictiona ...

最新文章

  1. 最“燃”研究生!浙工大 64 岁研究生毕业,老师称其毕业论文写的最好
  2. 定时器里面的作用域问题
  3. 槽点才是G点,LiveVideoStack主编是如何吐槽内容的?
  4. li或dd 浮动后增加图片时高度多出3-5px的问题
  5. 钢笔墨水能否代替打印机墨水_LAMY钢笔应该如何选择墨水?
  6. 小程序 国际化_在国际化您的应用程序时忘记的一件事
  7. 没错!现在搞 Python 越来越难了!!
  8. ZOJ 3804 YY's Minions (简单模拟)
  9. android语音识别开源代码,android语音识别,有没有相应的源码,教程可以推荐啊?
  10. MyEclipse中搭建spring-boot+mybatis+freemarker框架
  11. MySQL中会用到age字段的索引_MySQL学习笔记(四):正确使用索引(二)
  12. python 拼音 四线格_Python 中拼音库 PyPinyin 的用法
  13. MSMQ 消息队列的封装
  14. 智慧食堂管理系统打造健康食堂新理念
  15. 加密卡华为怎么模拟_华为手机NFC模拟加密的门禁卡详细教程
  16. 影视源码更新MKCMS影视系统6.3完整版源码
  17. 自动售货机软件工程课设_软件工程饮料自动售货机系统-.doc
  18. 使用HTML语言和CSS开发商业站点_利用CSS3制作网页动画
  19. python输出n的32次方_在Python中,如何将2的32次方-1的值存放到g中?
  20. 复化梯形公式matlab实验报告_复化梯形公式matlab

热门文章

  1. 一个简单的案例带你入门Dubbo分布式框架
  2. poj2154Color polya定理+欧拉函数优化
  3. Atitit.rust语言特性 attilax 总结
  4. 不能使用缺陷数据作为绩效度量
  5. ASP.NET2.0数据操作之创建数据访问层(3)
  6. 异步复位同步释放_简谈同步复位和异步复位
  7. 判断是否是数组的方法
  8. Java黑皮书课后题第6章:**6.22(数学:平方根的近似求法)实现Math类中dsqrt方法的技术:巴比伦法nextGuess = (lastGuess + n / lastGuess) / 2
  9. C语言学习之试编程从键盘输入2*3的二维数组,将该数组行列交换输出。
  10. 7.利用级数展开式计算求cos(x) 的近似值(精度为10-6)。