【发布时间】:2018-10-31 02:18:57
【问题描述】:
问题:
给定两个单词(beginWord 和 endWord)和字典的单词列表, 找到从 beginWord 到的所有最短转换序列 endWord,这样:
一次只能更改一个字母。每个转换后的单词必须 存在于单词列表中。请注意,beginWord 不是转换后的单词。
示例 1:
输入:beginWord = "hit", endWord = "齿轮", 单词表 = ["hot","dot","dog","lot","log","cog"]
输出:[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
我的解决方案就是基于这个思路,但是如何分析这个解决方案的时间和空间复杂度呢?
1) 从 beginWord 开始执行 BFS,将每个字母转换为 26 个字母之一,并查看转换后的单词是否在 wordList 中,如果是,则放入队列中。
2) 在 BFS 期间,为所有有效的 next 维护一个 {word:nextWord} 的图 话
3) 当一个nextWord到达endWord时,做一个回溯DFS(预购 traversal) 在图上获取所有路径。
class Solution:
def findLadders(self, beginWord, endWord, wordList):
"""
:type beginWord: str
:type endWord: str
:type wordList: List[str]
:rtype: List[List[str]]
"""
wordListSet = set(wordList+[beginWord])
graph = collections.defaultdict(list)
q = set([beginWord])
count = 0
result = []
while q:
count +=1
newQ = set()
for word in q:
wordListSet.remove(word)
for word in q:
if word == endWord:
self.getAllPaths(graph, beginWord, endWord, result, [])
return result
for i in range(len(word)):
for sub in 'abcdefghijklmnopqrstuvwxyz':
if sub != word[i]:
newWord = word[:i] + sub + word[i+1:]
if newWord in wordListSet:
graph[word].append(newWord)
newQ.add(newWord)
q = newQ
return []
def getAllPaths(self, graph, node, target, result, output):
#This is just a backtracking pre-order traversal DFS on a DAG.
output.append(node)
if node==target:
result.append(output[:])
else:
for child in graph[node]:
self.getAllPaths(graph,child, target, result, output)
output.pop()
我很难想出它的时间和空间复杂性。 我的论点:
时间:O(26*L*N + N),其中L 是每个单词的平均长度,N 是 wordList 中的单词数。最坏的情况是每个转换的单词都恰好在列表中,所以每个转换都需要26 * length of word。 DFS 部分只是O(N)。所以渐近地它只是O(L*N)
空格:O(N)
【问题讨论】:
-
您不确定争论的哪一部分,为什么?
-
我不确定时间复杂度,它似乎需要大于线性,但我无法说服自己。
-
当(潜在)出度固定时,图搜索在图的大小上是线性的,如下所示。
-
我的观察是否正确,字典属性(按字母顺序排序)在一般情况下没有帮助,因为前导字符的变化使订单一文不值?
-
这不是问题,但是您是否考虑过使用 levenshtein 距离?它将以 O(N * L**2) (根据您的符号)计算它,这比您的解决方案渐进地差。但在许多情况下更好(因为 L
标签: python time-complexity breadth-first-search