词语阶梯(leetcode127 Word Ladder)
题目:一直两个单词(分别是起始单词与结束单词),一个单词词典,根据转换规则计算从起始单词到结束单词的最短转换步数。
转换规则:
- 在转换时,只能转换单词中的一个字符。
- 转换得到的新单词,必须在单词词典中。
例如:beginWord = “hit”;endWord = “cog”;wordList = [“hot”,”dot”,”dog”,”lot”,”log”,”cog”],最短转换方式为:“hit”->”hot”->”dot”->”dog”->”cog”,结果为5.
思考与分析
单词与单词之间的转换,可以理解为一张图,图的顶点为单词,若两单词之间可以互相转换,则这两个单词所代表的顶点间有一条边,求图中节点(beginWord)到节点(endWord)所有路径中,最少包括多少个节点。即图的宽度优先搜索。
- 构造单词的邻接矩阵
python代码
graph = {}
def connect(self,word1,word2):
count = 0
for i in range(len(word1)):
if word1[i] != word2[i]:
count +=1
return count ==1
def construct_graph(self,beginword,wordlist,graph):
wordlist.append(beginword)
for i in range(len(wordlist)):
left = []
right = []
for j in range(i+1,len(wordlist)):
if self.connect(wordlist[i],wordlist[j]):
if wordlist[i] not in graph.keys():
left.append(wordlist[j])
graph[wordlist[i]] = list(set(left))
else:
graph[wordlist[i]].append(wordlist[j])
if wordlist[j] not in graph.keys():
right.append(wordlist[i])
graph[wordlist[j]] = list(set(right))
else:
graph[wordlist[j]].append(wordlist[i])
return graph
算法整体思路
- 给定图的起点beginword,终点endword,图graph,从beginword
开始宽度优先搜索图graph,搜索过程中记录到达步数; - 设置搜索队列Q,设置集合visit,记录搜索过的顶点,将(beginword,1)添加到队列
- 只要队列不空,取出队列头部元素
(1)若取出的队列头部元素为endword,返回到达当前节点的步数
(2)否则扩展该节点,将与该节点相邻的且未添加到visit中的节点与步数同时添加到队列Q,并将扩展节点加入visit
4.若最终都无法搜索到endword,则返回0
def BFS_graph(self,beginword,endword,graph):
Q = []
step = {}
step[beginword] = 1
visit = []
Q.append(step)
visit.append(beginword)
# print(graph)
while len(Q) != 0:
node = Q[0]
key = list(node.keys())
# print(key[0])
# print(node)
# print(node.items())
step1 = list(Q[0].values())[0]
if key[0] == endword:
return step1
Q.pop(0)
neighbors = graph[key[0]]
# print(neighbors)
print(visit)
print(Q)
for i in range(len(neighbors)):
if neighbors[i] not in visit:
step = {}
# if visit.index(neighbors[i]) == visit[-1]:
step[neighbors[i]] = step1 +1
Q.append(step)
visit.append(neighbors[i])
def ladderLength(self,beginword,endword,wordlist):
graph1 = self.construct_graph(beginword,wordlist,self.graph)
return self.BFS_graph(beginword,endword,graph1)
if __name__ == "__main__":
beginword = "hit"
endword = "cog"
wordlist = []
wordlist.append("hot")
wordlist.append("dot")
wordlist.append("dog")
wordlist.append("lot")
wordlist.append("log")
wordlist.append("cog")
S = Solution()
result = S.ladderLength(beginword,endword,wordlist)
print(result)