Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:
- Only one letter can be changed at a time
- 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"]
Return
[ ["hit","hot","dot","dog","cog"], ["hit","hot","lot","log","cog"] ]
Note:
- Return an empty list 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.
Subscribe to see which companies asked this question.
广搜。
最开始的做法,也就是被注释掉的那个,是最平白直叙的方式做的,39个case,过了23个。
结果是超时了。是因为,用了set保存了当前的全部路径,这个开销还是很大的。
然后看了别人的做法,不应该保存整个路径,只保存每个节点的父节点就行了,这样会省下好多空间
class Solution(object):
def findLadders(self, beginWord, endWord, wordList):
'''
def check(s1,s2):
if abs(len(set(s1)) - len(set(s2))) > 1:
return False
count = 0
#print s1,s2,
for i in xrange(len(s1)):
if s1[i] != s2[i]:
count += 1
#print count
return count == 1
b = beginWord
e = endWord
l = wordList
res = []
cur = (b,)
res = [cur]
v = set()
count = 0
''' '''
flag = 1
while flag:
count += 1
tres = res[:]
res = []
for cur in tres:
for i in l:
if i not in cur and cur + (i,) not in v and check(cur[-1],i):
#print cur + (i,)
res += cur + (i,),
#print len(res)
if res == []:
return []
tres = []
for i in res:
#print i,i[-1],e
if len(i) > len(l):
return []
if i[-1] == e:
flag = 0
tres += list(i),
return tres
'''
#def findLadders(self, start, end, dic):
start = beginWord
end = endWord
dic = set(wordList)
#dic.add(end)
level = {start}
# 记录父节点是谁
parents = collections.defaultdict(set)
while level and end not in parents:
next_level = collections.defaultdict(set)
#对每一层进行遍历
for node in level:
#根据字母来进行遍历
for char in string.ascii_lowercase:
#分别放进每个位置里
for i in range(len(start)):
n = node[:i]+char+node[i+1:]
# 如果n在字典里,并且n目前还不是前驱
if n in dic and n not in parents:
next_level[n].add(node)
print level
print parents
print next_level
print ''
level = next_level
parents.update(next_level)
res = [[end]]
print parents
while res and res[0][0] != start:
res = [[p]+r for r in res for p in parents[r[0]]]
return res
"""
:type beginWord: str
:type endWord: str
:type wordList: List[str]
:rtype: List[List[str]]
"""