127. 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 transformed word must exist in the word list. Note that beginWord is not a transformed word.

For example,

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

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.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

 

UPDATE (2017/1/20):
The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.

 

这道题是经典的广度有优先搜索的例子,也是Dijkstra's algorithm的变形。
以题目给出的例子为例,其实就是在所有路径的权重都为1的情况下求出下列无向图中从节点hit到节点cog的最短路径:

 
Paste_Image.png

PS:图中相互之间只相差一个字母的单词都是相邻节点。

 

利用BFS算法,维持两个集合: visited 和 wordSet

 
Paste_Image.png

从hit开始出发,找到唯一的相邻节点:hot, 把它放进visited中,第一次循环结束。 PS: 所谓找到相邻的节点,在题目中就是找出和该单词之相差一个字母的所有单词。请看最后代码的详细实现。

 
Paste_Image.png

查看hot节点的所有相邻节点(已经被访问过的hit除外),找到lot和dot, 放进visited中。第二次循环结束。

 
Paste_Image.png

找出新家进来的lot和dot的未被访问的相邻节点,分别是log和dog放进visited中。第三次循环结束。

 
Paste_Image.png

找出log的未被访问的相邻节点cog,放进结合中。第四次循环结束。由于cog就是endWord,任务结束,跳出循环。

 
Paste_Image.png

这里总共经历了四次循环,每循环一次,其实就是从beginWord想endWord变化的一步,因此循环的次数(加上1)就是从beginWord想endWord转变经历的 number of steps。



 1 class Solution:
 2     def ladderLength(self, beginWord, endWord, wordList):
 3         """
 4         :type beginWord: str
 5         :type endWord: str
 6         :type wordList: List[str]
 7         :rtype: int
 8         """
 9         wordList = set(wordList)
10         visited = [beginWord]
11         visited = set(visited)
12         dist = 1
13         
14         while endWord not in visited:
15             temp = set()
16             for word in visited:
17                 for i in range(len(word)):
18                     newwordL = list(word)
19                     for ch in 'qwertyuiopasdfghjklzxcvbnm':
20                         newwordL[i] = ch
21                         newWord = ''.join(newwordL)
22                         if newWord in wordList:
23                             temp.add(newWord)
24                             wordList.remove(newWord)
25 
26             dist += 1
27             if len(temp) == 0: # if 0, it never gets to the endWord
28                 return 0
29 
30             visited = temp
31 
32         return dist

 


参考链接:https://www.jianshu.com/p/753bd585d57e

转载于:https://www.cnblogs.com/zle1992/p/8476064.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值