
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
if endWord not in wordList:
return 0
wordList = set(wordList)
queue = [(beginWord, 1)]
while queue:
curWord, level = queue.pop(0)
if curWord == endWord:
return level
for i in range(len(curWord)):
for j in 'abcdefghijklmnopqrstuvwxyz':
word = curWord[:i] + j + curWord[i+1:]
if word in wordList:
wordList.remove(word)
queue.append((word, level + 1))
return 0
126. 单词接龙 II

class Solution:
def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[List[str]]:
wordList = set(wordList)
if endWord not in wordList:
return []
res, visited, length = [], set(), 2
forward, backward = {beginWord: [[beginWord]]}, {endWord: [[endWord]]}
while forward:
if len(forward) > len(backward):
forward, backward = backward, forward
tmp = {}
while forward:
word, paths = forward.popitem()
visited.add(word)
for i in range(len(word)):
for c in 'abcdefghijklmnopqrstuvwxyz':
new = word[:i] + c + word[i+1:]
if new in backward:
if paths[0][0] == beginWord:
res.extend(fPath + bPath[::-1] for fPath in paths for bPath in backward[new])
else:
res.extend(bPath + fPath[::-1] for fPath in paths for bPath in backward[new])
if new in wordList and new not in visited:
tmp[new] = tmp.get(new, []) + [path + [new] for path in paths]
length += 1
if res and length > len(res[0]):
break
forward = tmp
return res
472. 连接词
