《Leetcode》127. 單詞接龍

給定兩個單詞(beginWord 和 endWord)和一個字典,找到從 beginWord 到 endWord 的最短轉換序列的長度。轉換需遵循如下規則:

每次轉換隻能改變一個字母。
轉換過程中的中間單詞必須是字典中的單詞。
說明:

如果不存在這樣的轉換序列,返回 0。
所有單詞具有相同的長度。
所有單詞只由小寫字母組成。
字典中不存在重複的單詞。
你可以假設 beginWord 和 endWord 是非空的,且二者不相同。

示例 1:

輸入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

輸出: 5

解釋: 一個最短轉換序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
     返回它的長度 5。

示例 2:

輸入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

輸出: 0

解釋: endWord "cog" 不在字典中,所以無法進行轉換。

思路:

1、題目分析

題目要求每個單詞只能做一個單詞的變化,然後轉換到endWord,求這個轉換的最短距離。

2、解題分析

看到最短距離就想到了用BFS算法,再圖的遍歷過程中BFS算法算是一個比較經典的算法。能找出無向圖從起點到終點的最短距離,所以嘗試着把這個題目轉換一下看能否轉換成一個圖。這個時候如過兩個單詞之間差一個變換,那就說明兩個節點之間的距離就是1.這樣就可以轉換成圖的遍歷。但是存在一個問題,每個單詞的變化都是有三種變化,那對應得wordlist裏可能也有很多對應得word。爲了簡化這個情況把wordlist進行處理。把不相同得那個單詞用*代替,然後把同類得放在一個value下面。處理完以後再把初始單詞和初始長度添加到一個隊列中去。在遍歷隊列。如果把每個單詞得變化都在字典中去查找,如果查找到得結果等於endword,萬事大吉,遍歷結束。如果不是endword。那把節點添加到對列,並且長度加1.不過這塊很容易出現環形結構,爲了不讓出現環形結構那麼實現聲明一個數組就存儲訪問過的節點。如果節點不在標記數組中才添加到隊列,否則不添加到隊列,繼續遍歷。

解題步驟:

①簡化、處理wordlist

②遍歷每個word的三種情況

③觀察是否等於endword或者是否不在標記數組中

④最後返回長度

先放代碼,然後畫圖梳理:

class Solution:
    def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
        #如果這個endword不在wordlist中 返回結果就是0
        if endWord not in wordList:
            return 0
        
        #聲明隊列和數組以及單詞長度
        queue  = collections.deque()
        dic = collections.defaultdict(list)
        L = len(beginWord)
        
        #處理列表中的單詞,將他們返回成統一格式的字符
        for item in wordList:
            for i in range(L):
                dic[item[:i]+"*"+item[i+1:]].append(item)
        print(dic)
        #添加一個元組到隊列中,單詞和當前層數,也就是距離
        queue.append((beginWord,1))
        
        #標記數組,防止出現環
        visit = {beginWord:True}
        
        while queue:
            cur,level = queue.popleft()
            for i in range(L):
                current = cur[:i]+'*'+cur[i+1:]

                #查找當前的元素在不在字典的value中
                for current in dic[current]:
                    if current==endWord:
                        return level+1
                    #如果不再標記數組中,添加進去然後更新隊列
                    if current not in visit:
                        visit[current]=True
                        queue.append((current,level+1))
        return 0

畫圖:
 

總結:我以爲我明白了BFS,其實我還是個弟弟。不會抽象問題,然後用數據結構的思想去解決。 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章