LeetCode127. Word Ladder (思路及python解法)

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

  1. Only one letter can be changed at a time.
  2. Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

Note:

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

Example 1:

Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

Output: 5

Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

这道题纠结了很长时间。自己写的一些方法都超时了,后来看的discuss,学到了一些新内容;

首先是deque 双边队列(double-ended queue)https://blog.csdn.net/happyrocking/article/details/80058623

d = collections.deque([])
d.append('a') # 在最右边添加一个元素,此时 d=deque('a')
d.appendleft('b') # 在最左边添加一个元素,此时 d=deque(['b', 'a'])
d.extend(['c','d']) # 在最右边添加所有元素,此时 d=deque(['b', 'a', 'c', 'd'])
d.extendleft(['e','f']) # 在最左边添加所有元素,此时 d=deque(['f', 'e', 'b', 'a', 'c', 'd'])
d.pop() # 将最右边的元素取出,返回 'd',此时 d=deque(['f', 'e', 'b', 'a', 'c'])
d.popleft() # 将最左边的元素取出,返回 'f',此时 d=deque(['e', 'b', 'a', 'c'])
d.rotate(-2) # 向左旋转两个位置(正数则向右旋转),此时 d=deque(['a', 'c', 'e', 'b'])
d.count('a') # 队列中'a'的个数,返回 1
d.remove('c') # 从队列中将'c'删除,此时 d=deque(['a', 'e', 'b'])
d.reverse() # 将队列倒序,此时 d=deque(['b', 'e', 'a'])

然后是set()方法进行查找:set内部实现是dict的。在in操作上是O(1),强于list

https://blog.csdn.net/acbattle/article/details/97012800

最后再来讲讲这个算法,还是BFS的思路。

重点的就是构造newword,比如hot,就会构建出aot,bot,cot...hat,hbt,hct...hoa,hob...会构建出26×len(word)个newword

而newword in wordList操作的时间复杂度为O(1)所以速度也很快

class Solution(object):
    def ladderLength(self, beginWord, endWord, wordList):
        """
        :type beginWord: str
        :type endWord: str
        :type wordList: List[str]
        :rtype: int
        """
        wordList = set(wordList)
        import collections
        bfs = collections.deque()
        bfs.append([beginWord,1])
        while bfs:
            word, length = bfs.popleft()
            if word == endWord:
                return length
            for i in range(len(word)):
                for letter in "abcdefghijklmnopqrstuvwxyz":
                    newword = word[:i] + letter + word[i+1:]
                    if newword in wordList and newword != word:
                        wordList.remove(newword)
                        bfs.append([newword, length+1])
        return 0

 

你可能感兴趣的:(Python,LeetCode)