算法(python)11 宽度优先搜索

词语阶梯(leetcode127 Word Ladder)
题目:一直两个单词(分别是起始单词与结束单词),一个单词词典,根据转换规则计算从起始单词到结束单词的最短转换步数。
转换规则:

  1. 在转换时,只能转换单词中的一个字符。
  2. 转换得到的新单词,必须在单词词典中。
    例如:beginWord = “hit”;endWord = “cog”;wordList = [“hot”,”dot”,”dog”,”lot”,”log”,”cog”],最短转换方式为:“hit”->”hot”->”dot”->”dog”->”cog”,结果为5.

思考与分析
单词与单词之间的转换,可以理解为一张图,图的顶点为单词,若两单词之间可以互相转换,则这两个单词所代表的顶点间有一条边,求图中节点(beginWord)到节点(endWord)所有路径中,最少包括多少个节点。即图的宽度优先搜索。

  1. 构造单词的邻接矩阵
    算法(python)11 宽度优先搜索_第1张图片
    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

算法整体思路

  1. 给定图的起点beginword,终点endword,图graph,从beginword
    开始宽度优先搜索图graph,搜索过程中记录到达步数;
  2. 设置搜索队列Q,设置集合visit,记录搜索过的顶点,将(beginword,1)添加到队列
  3. 只要队列不空,取出队列头部元素

(1)若取出的队列头部元素为endword,返回到达当前节点的步数
(2)否则扩展该节点,将与该节点相邻的且未添加到visit中的节点与步数同时添加到队列Q,并将扩展节点加入visit

4.若最终都无法搜索到endword,则返回0
算法(python)11 宽度优先搜索_第2张图片

    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)

你可能感兴趣的:(算法(python)11 宽度优先搜索)