题目:126. Word Ladder II
https://leetcode.com/problems/word-ladder-ii/
Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
Note:
Example 1:
Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]
Output:
[
["hit","hot","dot","dog","cog"],
["hit","hot","lot","log","cog"]
]
Example 2:
Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]
Output: []
Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
题目大意:
给一个开始的单词,一个结尾单词,给一个字典,每次只能动一个字母,输出最短变动路径的路径,可能存在多个解全部要打印出来。
这题是127 的升级版本,要先做127 才能理解126的BFS,看了网上和leetcode讨论区的答案,还是觉得下面这个python 答案最厉害。
思路跟127一样,得一个一个单词一个一个字母替换看在不在字典里面,在的话存起来,再在新的这个单词里面接着找下一个,一直到找到,找不到就是没有答案。不同的是这题要返回整个路径,那么不得不找一个layer这个东西,记录能到这层的前面的单词路径。
那么算法开始,layer 里面 beginWord 这一层只有beginWord一个,往下while循环,newlayer 建一个defaultdict的类型,开始for循环,在layer里面的每一个单词,如果就是endWord了,那么这一层所有的单词都要extend进来,layer[w]的意思是:能达到单词w的全部单词组合。
如果没有,那么开始从头替换,这个和127是一样的,唯一的区别就是如果在wordlist里面,newlayer[newword]里面要保存所有能够达到newword的单词组合,也是layer[w]。
下面是比较神奇的一步:
wordlist -=set(newlayer.keys())
我的理解是把这一层里面所有的单词都删除是因为这些是最先到达的,如果后面再有达到这些单词的,肯定是没有当前的快了,所以删除一整层会确保最短路径。 (如果理解有误欢迎指正)
class Solution:
def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:
wordlist=set(wordList)
res= []
layer = {}
layer[beginWord] = [[beginWord]]
while layer:
newlayer = collections.defaultdict(list)
for w in layer:
if w == endWord:
res.extend(k for k in layer[w])
else:
for i in range(len(w)):
for c in "abcdefghijklmnopqrstuvwxyz":
newword=w[:i] + c + w[i+1:]
if newword in wordlist:
newlayer[newword] += [j+[newword] for j in layer[w]]
wordlist -=set(newlayer.keys())
layer = newlayer
return res