127. Word Ladder 单词接龙
生活随笔
收集整理的這篇文章主要介紹了
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 单词接龙的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1470. Shuffle the Ar
- 下一篇: 2019\National _C_C++