word ladder 2
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 intermediate word must exist in the word list
For example,
Given:
beginWord = “hit”
endWord = “cog”
wordList = [“hot”,”dot”,”dog”,”lot”,”log”]
Return
[
[“hit”,”hot”,”dot”,”dog”,”cog”],
[“hit”,”hot”,”lot”,”log”,”cog”]
]
Note:
All words have the same length.
All words contain only lowercase alphabetic characters.
算法:
同样是最短路径问题,应该使用BFS。
但是,结果要求得到所有最短路径。
这时仅仅有BFS是不够的,我们需要构建从起点到终点的倒序图。
这就需要BFS以父层,子层遍历的形式进行搜索。
为了得到最后的路径,要利用生成的图从终点进行回溯,直到得到所有最短路径。
from collections import defaultdict
class Solution(object):
def findLadders(self, start, end, wordDict):
"""
:type start: str
:type end: str
:type dict: Set[str]
:rtype: List[List[str]]
"""
# first build the child - father tree. tree is implemented by dict
# second get the path from the tree
tree = defaultdict(list)
wordDict.add(end)
curLevel = set()
nextLevel = set()
visited = set()
curLevel.add(start)
find = False
while curLevel and not find:
for node in curLevel:
visited.add(node)
for node in curLevel:
for scss in self.successor(node, wordDict):
if scss == end:
find = True
if scss not in visited:
nextLevel.add(scss)
tree[scss].append(node)
curLevel = nextLevel
nextLevel = set()
result = []
print('tree is', tree)
if find:
path = []
self.gener_path(tree, start, end, path, result)
return result
def gener_path(self, tree, start, word, path, result):
path = path + [word]
print(word, path, result)
if start == word:
result.append(list(reversed(path)))
else:
for father in tree[word]:
self.gener_path(tree, start, father, path, result)
def successor(self, curStr, wordDict):
result = []
curList = list(curStr)
for idx in range(len(curStr)):
for ele in 'abcdefghijklmnopqrstuvwxyz':
temp = curList[idx]
if ele != temp:
curList[idx] = ele
newStr = ''.join(curList)
curList[idx] = temp
if newStr in wordDict:
result.append(newStr)
return result
solution = Solution()
wordSet = set(["hot","cog","dog","tot","hog","hop","pot","dot"])
start = 'hot'
end = 'dog'
print(solution.findLadders(start,end,wordSet))
('tree is', defaultdict(<type 'list'>, {'hog': ['hot'], 'hop': ['hot'], 'pot': ['hot'], 'dog': ['hog', 'dot'], 'tot': ['hot'], 'cog': ['hog'], 'dot': ['hot']}))
('dog', ['dog'], [])
('hog', ['dog', 'hog'], [])
('hot', ['dog', 'hog', 'hot'], [])
('dot', ['dog', 'dot'], [['hot', 'hog', 'dog']])
('hot', ['dog', 'dot', 'hot'], [['hot', 'hog', 'dog']])
[['hot', 'hog', 'dog'], ['hot', 'dot', 'dog']]