Word Ladder

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 intermediate word must exist in the word list

For example,

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

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

Note:

    • Return 0 if there is no such transformation sequence.
    • All words have the same length.
    • All words contain only lowercase alphabetic characters.

这题一开始没有想到思路,上来直接用DFS做,寻找所有路径中的最短路径,显然在这题并非最优。最短路径使用BFS更为easy和合适。

这题主要需要注意的点是如何找到当前词的下一个词。1.如果从当前词直接在字典中查找相差一个字母的单词,复杂度为O(N*L),在N非常大的时候很容易超时。2.更简单的办法是直接对查词进行按位变化,生成下一个词,并确认字典中是否含有该词,复杂度为O(26*L*L)(最后一个L为拼接单词的复杂度)。2的复杂度在N非常大的情况下明显优于1。选用2。

这是一道比较坑的题目,主要问题在于python在这道题的情况下非常容易TLE。必须在遍历的时候,在dict中的删除该词,而不是另开一个hashset来保存是否遍历,代码如下:

class Solution(object):
    def ladderLength(self, beginWord, endWord, wordList):
        """
        :type beginWord: str
        :type endWord: str
        :type wordList: Set[str]
        :rtype: int
        """
        #shortest path, bfs on graph, each word in the dict is a node,  maintain hashset to record whether the node has been  visited
        if not wordList or not beginWord or not endWord or len(beginWord) != len(endWord):
            return 0
        queue = collections.deque()
        queue.append(beginWord)
        charSet = list(string.lowercase)
        minlen = 1
        while queue:
            num = len(queue) #获取当前步需要遍历的点,这样可以用一个queue实现非递归的BFS
            for _ in xrange(num):
                word = queue.popleft()
                for i in xrange(len(word)):
                    for j in xrange(26):
                        change = word[:i] + charSet[j] + word[i+1:] #生成新词的方式,用直接slice加拼接更方便,而不是list,str转换来转化去
                        if change == endWord:
                            return minlen+1
                        if change in wordList:
                            queue.append(change)
                            wordList.remove(change)#删除会遍历的词,现在添加的词在下一步一定会遍历,所以不冲突。
            minlen += 1
        return 0

 这题更优的解法是双端BFS,详见https://discuss.leetcode.com/topic/16983/easy-76ms-c-solution-using-bfs/8

原文地址:https://www.cnblogs.com/sherylwang/p/5723719.html