此题解采用了双向广度优先搜索(BFS)来找到从起始单词到结束单词的最短转换序列。使用两个字典start和end分别存储从起始单词和结束单词出发的可能路径。双向搜索的优势在于它可以从两个方向同时进行,当两边搜索相遇时,路径最短。每一轮迭代中,选择更小的字典进行扩展,以减少处理的单词数量。通过迭代当前字典中的所有单词,并对每个单词尝试改变每一个位置的字符,生成新词并检查是否存在于另一端的字典中或字典集wordSet中。如果生成的单词存在于对面的字典中,说明找到了一条路径。如果存在于wordSet中,则将其加入到临时字典tmp中,并从wordSet中删除,以防止重复访问。
时间复杂度: O(25nm)
空间复杂度: O(mn)
class Solution:
def findLadders(self, beginWord: str, endWord: str, wordList: List[str]) -> List[str]:
if beginWord == endWord: return 0
n = len(beginWord)
wordSet = set(wordList)
if endWord not in wordSet: return []
wordSet.remove(endWord)
start = defaultdict(list)
end = defaultdict(list)
start[beginWord].append(beginWord)
end[endWord].append(endWord)
while start:
if len(start) > len(end):
start, end = end, start # 优化搜索,始终扩展较小的字典
tmp = defaultdict(list)
for w in start:
for i in range(n):
for c in \"abcdefghijklmnopqrstuvwxyz\":
cur = w[:i] + c + w[i+1:]
if cur in end:
if start[w][0] == beginWord:
return start[w] + end[cur][::-1] # 如果起点开始的路径,则正序连接
else:
return end[cur] + start[w][::-1] # 如果终点开始的路径,则反序连接
if cur in wordSet:
tmp[cur] = start[w] + [cur] # 扩展新词,并记录路径
wordSet.remove(cur) # 移除已访问单词,避免重复访问
start = tmp
return [] # 如果无法连接,则返回空列表