题目
题目描述
字典 wordList 中从单词 beginWord 到 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> … -> sk:
每一对相邻的单词只差一个字母。
对于 1 <= i <= k 时,每个 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中。
sk == endWord
给你两个单词 beginWord 和 endWord 和一个字典 wordList ,返回 从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0 。
示例 1:
输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”,“cog”]
输出:5
解释:一个最短转换序列是 “hit” -> “hot” -> “dot” -> “dog” -> “cog”, 返回它的长度 5。
示例 2:
输入:beginWord = “hit”, endWord = “cog”, wordList = [“hot”,“dot”,“dog”,“lot”,“log”]
输出:0
解释:endWord “cog” 不在字典中,所以无法进行转换。
提示:
1 <= beginWord.length <= 10
endWord.length == beginWord.length
1 <= wordList.length <= 5000
wordList[i].length == beginWord.length
beginWord、endWord 和 wordList[i] 由小写英文字母组成
beginWord != endWord
wordList 中的所有字符串 互不相同
题解
这个问题可以通过广度优先搜索(BFS)来解决,因为BFS能够找到从起点到终点的最短路径。在这个问题中,每个单词可以被视为图中的一个节点,如果两个单词之间仅相差一个字母,则它们之间存在一条边。我们的目标是找到从 beginWord
到 endWord
的最短路径长度。
解决方案步骤
- 检查边界条件:首先检查
endWord
是否在wordList
中。如果不在,则直接返回0,因为无法完成转换。 - 构建图:使用 BFS 构建图,其中每个节点代表一个单词,边连接那些只有一个字符不同的单词。
- 执行BFS:从
beginWord
开始进行广度优先搜索,记录访问过的单词和到达当前单词的步数。 - 终止条件:当第一次遇到
endWord
时,返回当前的步数加一(因为步数是从0开始计数的)。如果遍历完所有可能的单词后仍未能到达endWord
,则返回0。
Python 实现
下面是具体的实现代码:
from collections import deque, defaultdict
def ladderLength(beginWord, endWord, wordList):
# 将 wordList 转换为集合以便快速查找
wordSet = set(wordList)
# 如果 endWord 不在 wordSet 中,直接返回0
if endWord not in wordSet:
return 0
# 初始化队列用于BFS,以及一个集合用于记录已访问的单词
queue = deque([(beginWord, 1)])
visited = set([beginWord])
# 构建通用状态的字典
all_combo_dict = defaultdict(list)
for word in wordSet:
for i in range(len(beginWord)):
all_combo_dict[word[:i] + "*" + word[i+1:]].append(word)
# 开始BFS
while queue:
current_word, level = queue.popleft()
for i in range(len(current_word)):
intermediate_word = current_word[:i] + "*" + current_word[i+1:]
# 遍历与当前单词只差一个字母的所有单词
for word in all_combo_dict[intermediate_word]:
if word == endWord:
return level + 1
if word not in visited:
visited.add(word)
queue.append((word, level + 1))
# 清除该层的单词以避免重复处理
all_combo_dict[intermediate_word] = []
return 0
解释
-
构建通用状态的字典:通过将每个单词中的每个字符替换为通配符
*
来创建一个通用状态字典。例如,“hot” 可以变成 “ot”,“ht”,“ho*”。这有助于快速找到只相差一个字符的单词。 -
BFS遍历:使用队列进行广度优先搜索,同时维护一个
visited
集合来避免重复访问同一个单词。每当我们找到endWord
时,立即返回当前的层级数加一,表示从beginWord
到endWord
的最短转换序列的长度。 -
终止条件:一旦找到
endWord
,就返回其所在的层级数加一。如果没有找到路径,则最终返回0。
这种方法确保了我们能够找到从 beginWord
到 endWord
的最短路径,并且效率上也较为合理,适合处理题目给定的输入规模。