126. 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:
Only one letter can be changed at a time
Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
Note:
Return an empty list if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.
You may assume no duplicates in the word list.
You may assume beginWord and endWord are non-empty and are not the same.
解释:
每次改动一个字符,从初始单词变换到最终单词,要求返回所有的路径。 有几个关键点: 单词长度都相同,单词不重复
思考:
题目也是非常经典的题目了,单词ladder,dfs/bfs的教程题。既然是求图的最短距离,还是用bfs来做比较直观一些。那么如何确定下一层谁进队列呢,这里有两种选择,一种是遍历整个字典,寻找和当前s只差一个字符的s1,但是其实这样很慢,尤其是当字典非常非常大的时候;另外一个选择是用根据当前s,每次修改一个字符,每次其实只有26^len(s)个选项,set查找的时间是O1的,会比较快。 如果end字符串出现在当前层内,那么只需要继续遍历完当前层返回即可。
答案:
class Solution:
def findLadders(self, beginWord, endWord, wordList):
from collections import defaultdict
if endWord not in wordList: return []
forward,backward,wordList,dic = {beginWord},{endWord},set(wordList),defaultdict(set)
flag,letters,length = True,set('qwertyuioplkjhgfdsazxcvbnm'),len(endWord)
while forward:
if len(forward) > len(backward):
forward,backward,flag = backward,forward,not flag
cur = set()
wordList -= forward
for word in forward:
for idx in range(length):
x,y = word[:idx],word[idx+1:]
for letter in letters:
temp = x + letter + y
if temp in wordList:
cur.add(temp)
if flag: dic[temp].add(word)
else: dic[word].add(temp)
if cur & backward:
res = [[endWord]]
while res[0][0] != beginWord:
res = [[x]+y for y in res for x in dic[y[0]]]
return res
forward = cur
return []
答案补充:
最后还是超时了,不知道原因在哪,不过就这样应该足够了。