欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

127. Word Ladder 单词接龙

发布时间:2024/5/17 55 豆豆
生活随笔 收集整理的这篇文章主要介绍了 127. Word Ladder 单词接龙 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:
  • 每次转换只能改变一个字母。
  • 转换过程中的中间单词必须是字典中的单词。
  • 说明:

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

    示例 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 为终点进行广度优先搜索,寻找 beginWord 到 endWord 的最短路径。

    根据给定字典构造的图可能会很大,而广度优先搜索的搜索空间大小依赖于每层节点的分支数量。假如每个节点的分支数量相同,搜索空间会随着层数的增长指数级的增加。考虑一个简单的二叉树,每一层都是满二叉树的扩展,节点的数量会以 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 单词接龙的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。