题目描述
给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:
每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。
说明:
- 如果不存在这样的转换序列,返回 0。
- 所有单词具有相同的长度。
- 所有单词只由小写字母组成。
- 字典中不存在重复的单词。
- 你可以假设 beginWord 和 endWord 是非空的,且二者不相同。
示例
示例 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" 不在字典中,所以无法进行转换。
解答方法
方法一:BFS
思路
https://leetcode-cn.com/problems/word-ladder/solution/dan-ci-jie-long-by-leetcode/
代码
from collections import defaultdict
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
if endWord not in wordList:
return 0
L = len(beginWord)
neighbour_dic = defaultdict(list)
for word in wordList:
for i in range(L):
neighbour_dic[word[:i] + '*' + word[i+1:]].append(word)
#BFS
queue = [(beginWord,1)]
mark_dic = defaultdict(bool)
mark_dic[beginWord] = True
while queue:
cur_word, level = queue.pop(0)
for i in range(L):
for neighbour in neighbour_dic[cur_word[:i]+'*'+cur_word[i+1:]]:
if neighbour== endWord:
return level+1
if not mark_dic[neighbour]:
mark_dic[neighbour] = True
queue.append((neighbour,level+1))
return 0
时间复杂度
,其中 M 是单词的长度 N 是单词表中单词的总数。找到所有的变换需要对每个单词做 M 次操作。同时,最坏情况下广度优先搜索也要访问所有的 N 个单词。
空间复杂度
,要在 neighbour_dic 字典中记录每个单词的 M 个通用状态。访问数组的大小是 N。广搜队列最坏情况下需要存储 N 个单词。
网友评论