Leetcode 127. Word Ladder BFS

2019-03-27  本文已影响0人  jl先生

127. Word Ladder(Medium)

这道题有收货,想拿出来分享一下。
搜索题,开始用BFS,妥妥的超时,看到shortest 最短的搜索一定要先想到用BFS。
首先是单向的BFS,从beginWord开始每次把每个单词的所有字母替换,用visited做标记。

        wordList = list(set(wordList))
        queue = [(beginWord,1)]
        visited = set()
        while queue:
            word,path = queue.pop(0)
            if word == endWord:
                return path
            for i in range(len(word)):
                for j in "abcdefghijklmnopqrstuvwxyz":
                    tmp = word[:i] + j + word[i+1:]
                    if tmp in wordList and tmp not in visited:
                        queue.append((tmp, path + 1))
                        visited.add(tmp)
        return 0

然而 [Time Limit Exceeded]
看了解析后发现双向BFS才能过,原理如图。
巧妙之处在于单向BFS是自顶向下的,而双向的每次bfs查看front队列和back 谁小,相对于取上还是取下取决于遍历次数,数据量大可以减少很多次的遍历。

image.png
    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
        if endWord not in wordList:
            return 0
        wordList = set(wordList)
        front, back = set([beginWord]), set([endWord])
        res = 1
        #双向BFS
        while front:
            res += 1
            tmp_queue = set()
            for word in front:
                for i in range(len(word)):
                    for c in "abcdefghijklmnopqrstuvwxyz":
                        if c != word[i]:
                            tmp = word[:i] + c + word[i+1:]
                            if tmp in back:
                                return res
                            if tmp in wordList: #注意set()的add与remove
                                tmp_queue.add(tmp)
                                wordList.remove(tmp)
            front = tmp_queue
            if len(front) > len(back): #关键点 减少bfs次数
                front, back = back, front
        return 0
上一篇下一篇

猜你喜欢

热点阅读