127. Word Ladder
題目網址:https://leetcode.cn/problems/word-ladder/
題意:一個 transform sequence 指的是
wordList
中從單字beginWord
到endWord
的 sequencebeginWord -> s1 -> s2 -> ... -> sk
, 且 transform sequence 需滿足以下條件:
- 相鄰的兩個單字只差一個字母
- 每個
si
都在wordList
中, 其中1 ≤ i ≤ k
。注意,beginWord
不需在wordList
中sk == endWord
給兩個單字
beginWord
和endWord
, 以及一字典wordList
, 返回從beginWord
到endWord
的最短 transform sequence 中的單字個數。若不存在這樣的 transform sequence, 則返回0
。注意:
wordList[i]
僅由小寫字母所組成。
Solution 1:
想法:看到最短路徑會直覺想到 Dijkstra, 但在 unweighted graph 中, 其實只需要用 BFS 就可求得最短路徑了。故利用 BFS, 從 queue
q
中取出當前的 wordcurWord
, 然後將每個curWord[i]
替換成a - z
的其他 char。若更改後的curWord
存在於dict
中, 則將其加到q
中, 並將其從dict
中刪除以避免下一輪中q
重複添加e.g.
hit -> hot -> hit
class Solution { |
- time:$O(n \cdot len)$ ➔ $O(n \cdot 26 \cdot len)$, 其中
n
為 word 的個數,len
為每個 word 的長度- $O(n)$:每一輪最少要從
wordList
中取一個 word, 故最多有n
輪, 總共最多取n
個 word - $O(26 \cdot len)$:每個 word 可產生 $26 * len$ 個單字
- $O(n)$:每一輪最少要從
- space:$O(n \cdot len)$ ➔
dict
儲存每個 word
Solution 2:
想法:利用 Bidirectional BFS(雙向 BFS), 從
beginWord
和endWord
兩端開始拓展, 兩端產生的 word 分別用s1
、s2
儲存, 讓s1
永遠為較小的 hash set, 這樣 for loop 進行拓展的 word 會比較少。一旦s1
的 word 所拓展出來的 new word 出現在s2
中, 代表兩端碰頭, 故返回res + 1
e.g.
wordList = ["hot","dot","dog","lot","log","cog"]
,begin = "hit"
,end = "cog"
- 一開始,
s1 = {hit}
,s2 = {cog}
- 第一輪,
s1
拓展 ➔s1 = {hit, hot}
,s2 = {cog}
- 第二輪
s1
和s2
先 swap ➔s1 = {cog}
,s2 = {hit, hot}
s1
拓展 ➔s1 = {cog, dog, log}
,s2 = {hit, hot}
- 第三輪
s1
和s2
先 swap ➔s1 = {hit, hot}
,s2 = {cog, dog, log}
s1
拓展 ➔s1 = {hit, hot, dot, lot}
,s2 = {cog, dog, log}
- 第四輪
s1
和s2
先 swap ➔s1 = {cog, dog, log}
,s2 = {hit, hot, dot, lot}
s1
拓展 ➔s1 = {cog, dog, log, dot}
, 發現dot
已出現在s2
中, 故中止
class Solution { |
- time:$O(n \cdot len)$ ➔ $O(n \cdot 26 \cdot len)$, 其中
n
為 word 的個數,len
為每個 word 的長度- $O(n)$:每一輪最少要從
wordList
中取一個 word, 故最多有n
輪, 總共最多取n
個 word - $O(26 \cdot len)$:每個 word 可產生 $26 * len$ 個單字
- $O(n)$:每一輪最少要從
- space:$O(n \cdot len)$ ➔
dict
儲存每個 word