相关题目
打开转盘锁 – BFS
关于双向BFS介绍:双向BFS
# 127. 单词接龙
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
self.wordId = dict()
self.edge = collections.defaultdict(list)
self.nodeNum = 0
for word in wordList:
self.addEdge(word)
self.addEdge(beginWord)
if endWord not in self.wordId:
return 0
disBegin = [float('inf')] * self.nodeNum
beginId = self.wordId[beginWord]
disBegin[beginId] = 0
queBegin = collections.deque([beginId])
disEnd = [float("inf")] * self.nodeNum
endId = self.wordId[endWord]
disEnd[endId] = 0
queEnd = collections.deque([endId])
while queBegin or queEnd:
queBeginSize = len(queBegin)
for _ in range(queBeginSize):
nodeBegin = queBegin.popleft()
if disEnd[nodeBegin] != float('inf'):
# 因为添加了虚拟节点,所以我们得到的距离为实际最短路径长度的两倍。
return (disBegin[nodeBegin] + disEnd[nodeBegin]) // 2 + 1
for it in self.edge[nodeBegin]:
if disBegin[it] == float('inf'):
disBegin[it] = disBegin[nodeBegin] + 1
queBegin.append(it)
queEndSize = len(queEnd)
for _ in range(queEndSize):
nodeEnd = queEnd.popleft()
if disBegin[nodeEnd] != float('inf'):
return (disBegin[nodeEnd] + disEnd[nodeEnd]) // 2 + 1
for it in self.edge[nodeEnd]:
if disEnd[it] == float('inf'):
disEnd[it] = disEnd[nodeEnd] + 1
queEnd.append(it)
return 0
def addWord(self, word: str):
if word not in self.wordId:
self.wordId[word] = self.nodeNum
self.nodeNum += 1
def addEdge(self, word: str):
self.addWord(word)
id1 = self.wordId[word]
chars = list(word)
# 创建虚拟节点。对于单词 hit,我们创建三个虚拟节点 *it、h*t、hi*,
# 并让 hit 向这三个虚拟节点分别连一条边即可。
for i in range(len(chars)):
tmp = chars[i]
chars[i] = '*'
newWord = ''.join(chars)
self.addWord(newWord)
id2 = self.wordId[newWord]
self.edge[id1].append(id2)
self.edge[id2].append(id1)
chars[i] = tmp