题目-困难难度
字典 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 中的所有字符串 互不相同
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/summary-ranges
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1. bfs
时间
388ms
击败 53.49%使用 Python3 的用户
内存
16.85MB
击败 76.93%使用 Python3 的用户
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
# 将wordList去重
wordList = set(wordList)
# 如果查询的单词不存在于wordList中,直接返回0
if endWord not in wordList:
return 0
# 初始查询的单词
q = {beginWord}
# 初始化步骤, 最低为2
step = 2
# 遍历单词
while q:
# 用于存储下一次遍历单词
tmp = set()
# 对于q中的单词
for word in q:
# 依次遍历单词的每一个字母
for i in range(len(word)):
# 替换单词的当前字母为a-z中其他的字母
for c in 'abcdefghijklmnopqrstuvwxyz':
# 生成替换后的新单词
newWord = word[:i] + c + word[i+1:]
# 如果替换后的单词就是目标单词
if newWord == endWord:
# 返回最终步骤数
return step
# 如果不是目标单词, 但是存在于单词列表中
if newWord in wordList:
# 添加到下次遍历
tmp.add(newWord)
# 从单词列表中移除当前单词, 防止重复
wordList.remove(newWord)
# 给q赋值下次需要遍历的单词
q = tmp
# 步骤数+1
step += 1
# 未能找到则返回0
return 0
2. bfs
超出时间限制
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
# 判断两个单词是否只有一个不同的方法
def oneDiff(l1,l2):
return sum(i!=j for i,j in zip(l1,l2)) == 1
# 获取wordList长度
lwl = len(wordList)
# 创建列表存储相关联并且一字之差的单词
adj = [[] for _ in range(lwl)]
# 为获取目标索引初始化一个索引
endIndex = -1
# 遍历列表项
for i, s in enumerate(wordList):
# 如果当前单词为目标单词, 获取它的索引
if s == endWord:
endIndex = i
# 将每个单词相差一个单词的单词, 放到关联链表
for j in range(i + 1, lwl):
if oneDiff(s, wordList[j]):
adj[i].append(j)
adj[j].append(i)
# 如果查询的单词不存在于结果列表内, 返回0
if endIndex == -1:
return 0
# 遍历找出与查询单词相近的单词
q = [i for i, s in enumerate(wordList) if oneDiff(beginWord, s)]
# 存储遍历过的单词
vis = set(q)
# 如果第一个就找到, 说明转换序列的长度为2
step = 2
# 遍历开始
while q:
# tmp获取q列表
tmp = q
# 将q列表赋值为空方便添加下一级遍历的单词
q = []
# 遍历最相近的单词
for cur in tmp:
# 如果找到了目标单词, 返回步数
if cur == endIndex:
return step
# 如果没找到, 遍历当前相近单词下的第二层相近的单词
for nxt in adj[cur]:
# 确保单词未被遍历的情况下,添加下一次遍历的单词
if nxt not in vis:
vis.add(nxt)
q.append(nxt)
step += 1
return 0