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:
- Only one letter can be changed at a time
- 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
posted on 2016-07-31 19:30 Sheryl Wang 阅读(155) 评论(0) 编辑 收藏 举报