优化字梯

时间:2019-10-30 13:43:36

标签: python algorithm

我正在尝试解决这个问题:

  

给出两个单词(beginWord和endWord),以及字典的单词列表,   查找从beginWord到的最短转换序列的长度   endWord,例如:

     

一次只能更改一个字母。每个变换的词必须   存在于单词列表中。注意beginWord不是转换后的单词。   注意:

     

如果没有这样的转换序列,则返回0。所有的单词都有   相同的长度。所有单词仅包含小写字母   字符。您可以假设单词列表中没有重复项。你可以   假设beginWord和endWord为非空并且不相同。

https://leetcode.com/problems/word-ladder/ 我正确的工作代码:

from collections import Counter, defaultdict, deque 
def can_change(x, y):
    diff = 0
    for u, v in zip(x, y):
        if u != v:
            diff += 1
        if diff>1:
            return False
    return diff == 1


class Solution:
    def ladderLength(self, start, end, dict):
        graph = defaultdict(list)
        words = set(dict+[start])
        for w1 in words:
            for w2 in words:
                if w1 != w2:
                    if can_change(w1, w2):
                        graph[w1].append(w2)
        def bfs(node):
            queue = deque([(node, 1)])
            seen = {node}
            while queue:
                node, count = queue.pop()
                if node == end:
                    return count
                for neb in graph[node]:
                    if neb not in seen:
                        seen.add(neb)
                        queue.appendleft((neb, count+1))
            return 0
        return bfs(start)

在大型测试用例上超时。如何在时间复杂度方面进行优化?

1 个答案:

答案 0 :(得分:0)

我会尽量避免使用邻接表显式定义图-我认为这是多余的。

相反,您可以尝试隐式运行BFS。 伪代码:

Q = empty queue 
beginWord.depth = 0
Q.enqueue(beginWord)  
while  Q is not empty:
    w = Q.dequeue
    for l in dictionary:
        if l is a one char transform on w:
              if l == endWord:
                  return w.depth+1 
              else:
                  l.depth = w + 1
                  Q.enqueue(l)
                  remove l from the dictionary.
return 0

我认为,此方法与您使用的BFS方法非常相似。它以BFS方式扫描“图形”,跟踪从beginWord可以找到的单词以及当前的搜索深度。如果找到endWord,则返回其深度。

这里的主要区别是我们不创建用于对整个字典建模的图形。我们确实扫描了广度优先样式的搜索,但我们避免跟踪以后不使用的信息-例如路径的边缘,不可达的单词等。

此处的渐近运行时间为O(nX),X是从beginWord可到达的单词数。在最坏的情况下,它不能胜过您的算法,但在其他许多情况下,它也可以。

它还为您节省了在构建图形之后必须执行的BFS搜索,并且将证明可以访问的单词从列表中删除,从而减少了常量。