Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
Only one letter can be changed at a time Each intermediate word must exist in the dictionary
Example Given: start = "hit" end = "cog" dict = ["hot","dot","dog","lot","log"] As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5.
Example Given: start = "hit" end = "cog" dict = ["hot","dot","dog","lot","log"] Return [ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Hint: 1. Use BFS from end to start to record the distance of node to end
2. DFS to record all shortest path
Map the distance of node to end
Map surrounding Nodes
注意在bfs時先把
deffindLadders(self,beginWord:str,endWord:str,wordList: List[str]) -> List[List[str]]:if endWord notin wordList:return [] self.wordDict =set(wordList)# Add beginWord to wordDict, otherwise it will not be update when BFS self.wordDict.add(beginWord) self.neighbors =defaultdict(list) self.distance =defaultdict(int) self.ans = []# use bfs to traverse from end to start, and record the nerghbors of each node and distance from end to each node# distance will be update as the shortest distance to end self.bfs(beginWord, endWord)# dfs to find out the route self.dfs([beginWord], endWord)return self.ansdefdfs(self,l,endWord): word = l[-1]if word == endWord: self.ans.append(l.copy())for next_word in self.neighbors[word]: l.append(next_word)# only go to next level if on the correct routeif self.distance[word]== self.distance[next_word]+1: self.dfs(l, endWord) l.pop()defbfs(self,beginWord,endWord): q = [] q.append(endWord) flag =Falsewhile q:if flag:break size =len(q)for i inrange(size): word = q.pop(0)for next_word in self.getNext(word):if next_word == beginWord: flag =True self.neighbors[next_word].append(word)# If we have seen the node distance means this one if farther distance. Not updateif next_word notin self.distance: self.distance[next_word]= self.distance[word]+1 q.append(next_word)defgetNext(self,word): next_list = []for i inrange(len(word)):for j inrange(26): ch =chr(ord('a') + j)if word[i]== ch:continue new_word = word[:i]+ ch + word[i+1:]if new_word in self.wordDict: next_list.append(new_word)return next_list