126. Word Ladder II
Title
給定兩個(gè)單詞(beginWord 和 endWord)和一個(gè)字典 wordList,找出所有從 beginWord 到 endWord 的最短轉(zhuǎn)換序列。轉(zhuǎn)換需遵循如下規(guī)則:
每次轉(zhuǎn)換只能改變一個(gè)字母。
轉(zhuǎn)換過(guò)程中的中間單詞必須是字典中的單詞。
說(shuō)明:
如果不存在這樣的轉(zhuǎn)換序列,返回一個(gè)空列表。
所有單詞具有相同的長(zhǎng)度。
所有單詞只由小寫字母組成。
字典中不存在重復(fù)的單詞。
你可以假設(shè) beginWord 和 endWord 是非空的,且二者不相同。
示例 1:
輸入:
beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]輸出:
[["hit","hot","dot","dog","cog"],["hit","hot","lot","log","cog"] ]示例 2:
輸入:
beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log"]輸出:
[]解釋: endWord “cog” 不在字典中,所以不存在符合要求的轉(zhuǎn)換序列。
Solve
將所有單詞構(gòu)建桶,便于查找鄰接詞。構(gòu)建桶的方式是依次將一個(gè)詞的各個(gè)字母挖空,用字典進(jìn)行保存
廣度優(yōu)先搜索進(jìn)行遍歷,這里構(gòu)建三個(gè)數(shù)據(jù)結(jié)構(gòu):
- beFound:用于標(biāo)記首次遍歷的詞,同時(shí)記錄首次遍歷的深度
- preWords:用一個(gè)默認(rèn)列表字典記錄到達(dá)該節(jié)點(diǎn)的前溯詞列表,需注意對(duì)于每個(gè)可能搜索到該詞的路徑,只要深度不超過(guò)已有路徑,都應(yīng)加入前溯詞列表
- toSeen:用一個(gè)雙端隊(duì)列存儲(chǔ)待遍歷詞及當(dāng)前深度。
如果搜索到了目標(biāo)節(jié)點(diǎn)endWord,則依次往前遞歸輸出解:每個(gè)解的頭節(jié)點(diǎn)若包含多個(gè)前溯詞,則解相應(yīng)增加。利用python列表嵌套推導(dǎo)式實(shí)現(xiàn)。
Code
class Solution:def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:length = len(beginWord)wordList.append(beginWord)# 構(gòu)建具有鄰接關(guān)系的桶buckets = defaultdict(list)for word in wordList:for i in range(length):match = word[:i] + '_' + word[i + 1:]buckets[match].append(word)print(buckets)# BFS遍歷preWords = defaultdict(list) # 前溯詞列表toSeen = deque([(beginWord, 1)]) # 待遍歷詞及深度列表beFound = {beginWord: 1} # 已探測(cè)詞詞列表while toSeen:curWord, level = toSeen.popleft()for i in range(len(beginWord)):match = curWord[:i] + '_' + curWord[i + 1:]for word in buckets[match]:if word not in beFound:beFound[word] = level + 1toSeen.append((word, level + 1))if beFound[word] == level + 1: # 當(dāng)前深度等于該詞首次遍歷深度,則仍應(yīng)加入前溯詞列表preWords[word].append(curWord)if endWord in beFound and level + 1 > beFound[endWord]: # 已搜索到目標(biāo)詞,且完成當(dāng)前層遍歷break# 列表推導(dǎo)式輸出結(jié)果if endWord in beFound:res = [[endWord]]while res[0][0] != beginWord:res = [[word] + r for r in res for word in preWords[r[0]]]return reselse:return []總結(jié)
以上是生活随笔為你收集整理的126. Word Ladder II的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: the NTP socket is in
- 下一篇: 990. Satisfiability