问答题
5. 给定一个词典和两个长度相同的“开始”和“目标”的单词。找到从“开始”到“目标”最小链的长度。如果它存在,那么这条链中的相邻单词只有一个字符不同,而链中的每个单词都是有效的单词,即它存在于词典中。可以假设词典中存在“目标”字,所有词典词的长度相同。
例如:
给定一个单词词典为:[pooN,pbcc,zamc,poIc,pbca,pbIc,poIN]
start=TooN
target=pbca
输出结果为:7
因为:TooN (start)-pooN-poIN-poIc-pbIc-pbcc-pbca(target).
【正确答案】本题主要的解决方法为:使用BFS的方式从给定的字符串开始遍历所有相邻(两个单词只有一个不同的字符)的单词,直到遍历找到目标单词或者遍历完所有的单词为止。实现代码如下:
from collections import deque
#用来存储单词链的队列
class QItem:
def _init__(self,word,lens):
self.word=word
self.lens=lens
#判断两个字符串是否只有一个不同的字符
def isAdjacent(a,b):
diff=0
lens=len(a)
i=0
while i<lens:
if list(a)[i]!=list(b)[i]:
diff+=1
if diff>1:
return False
i+=1
return diff==1
#返回从start到target的最短链
def shortestChainLen(start,target,D):
Q=deque()
item=QItem(start,1)
Q.append(item) #把第一个字符串添加进来
while len(Q)>0:
curr=Q[0]
Q.pop()
for it in D:
temp=it
#如果这两个字符串只有一个字符不同
if isAdjacent(curr.word,temp):
item.word=temp
item.lens=curr.lens+1
Q.append(item) #把这个字符串放入到队列中
#把这个字符串从队列中删除来避免被重复遍历
D.remove(temp)
#通过转变后得到了目标字符
if temp==target:
return item.lens
return 0
if __name__="__main__":
D=[]
D.append("pooN")
D.append("pbcc")
D.append("zamc")
D.append("polc")
D.append("pbca")
D.append("pblc")
D.append("poIN")
start="TooN"
target="pbca"
print "最短的链条的长度为: "+str(shortestChainLen(start, target, D))
程序的运行结果为:
最短的链条的长度为:7
算法性能分析:
这种方法的时间复杂度为O(n2m),其中n为单词的个数,m为字符串的长度。
【答案解析】[考点] 如何查找到达目标词的最短链长度