leetcode 126. word ladder ii 中文解釋 chinese version
該題思路為bfs+dfs.
用bfs標記最短距離, 並記錄前驅節點
用dfs從終點遍歷回起點
如bfs+dfs,有幾個超時的坑所說, 要作兩個優化:
bfs時建立反向鄰接表獲取鄰近單詞時, 要列舉其可能的鄰近單詞來收集, 而不能遍歷所有單詞逐一比對, 因為單詞量很大時, 耗時較多。
得出如下**:
import queue
class
solution
:def
dfs(self, cur, path, endword, words, res)
:if cur == endword:
r_path = path.copy(
) r_path.reverse(
) path.pop(
)return
for pred in words[cur][1
]:self.dfs(pred, path, endword, words, res)
path.pop(
)def
bfs(self, start_set, words, dist, end_word, found):if
not start_set or found:
return
next_set =
set(
)for word in start_set:
if word == end_word:
found =
true
return
# 列舉每個可能的鄰近單詞
for i in
range
(len
(word)):
for j in
range
(ord
('a'),
ord(
'z')+1
):w = word[
:i]+
chr(j)
+ word[i+1:
]if w in words and dist+
1<= words[w][0
]:words[w][0
]= dist+
1 next_set.add(w)
words[w][1
] self.bfs(next_set, words, dist+
1, end_word, found)
deffindladders
(self, beginword:
str, endword:
str, wordlist)
: words =
dict()
for word in wordlist:
words[word]=[
float
("inf"),
]# dist, preds
words[beginword]=[
0,]if endword not
in words:
return
self.bfs(
, words,
0, endword,
false
) res =
self.dfs(endword,
, beginword, words, res)
return res
這裡有幾個注意的點:
words記錄的兩個變數含義, 分別為從源節點出發的最短距離, 和最短路徑的前驅節點.
words =
dict()
for word in wordlist:
words[word]=[
float
("inf"),
]# dist, preds
words[beginword]=[
0,]
words[w][0]
只有兩個可能的值,float("inf")
代表該節點還沒被訪問過, dist代表該節點的最短距離.
通過逐一變換單詞中某個字母來列舉可能鄰近的單詞:
for i in
range
(len
(word)):
for j in
range
(ord
('a'),
ord(
'z')+1
):w = word[
:i]+
chr(j)
+ word[i+1:
]
判斷是否標記最短距離的時候, 合併了兩條邏輯.
if w in words and dist+
1<= words[w][0
]:words[w][0
]= dist+
1 next_set.add(w)
words[w][1
]
如果w in words
, 我們能確定w與word之間有邊, 此時有三種情況:
如果words[w][0]
為flaot("inf")
, 它一定沒被訪問過, 有dist+1 < words[w][0]
, 要標記最短距離, 並加入前驅節點
否則words[w][0]
是最短距離,dist+1
不可能比它更小
如果相等, 說明是在同一層中, 以同樣的最短路徑訪問到w, 也要加入前驅節點. (此時words[w][0] = dist+1
和next_set.add(w)
操作無***, 為了**簡單, 與第一條並在一起寫了)
否則, 以非最短距離訪問到w(繞遠路了).有dist+1 > words[w][0]
, 不作任何操作.
合併邏輯1.和2.1, 則當dist+1 <= words[w][0]
時, 都要加入前驅節點, 且加入next_set
, 下一輪bfs要遍歷.
(此處自行腦補三種情況的圖)
最後dfs從終點遍歷回起點, 遇到起點時加入結果集, 記得加入翻轉的路徑:
if cur == endword:
r_path = path.copy(
) r_path.reverse(
) path.pop(
)return
本題考驗在bfs中記錄最短距離和最短路徑前驅節點的操作.
然後是利用前驅節點, 從終點dfs回到起點的操作
leetcode 126 單詞接龍2
給定兩個單詞 beginword 和 endword 和乙個字典 wordlist,找出所有從 beginword 到 endword 的最短轉換序列。轉換需遵循如下規則 每次轉換只能改變乙個字母。轉換過程中的中間單詞必須是字典中的單詞。說明 示例 1 輸入 beginword hit endwor...
126 單詞接龍 II
題目.high 這其實就是圖的演算法,dijkstra演算法 這道題,先求直達的最小路徑,這個用bfs沒啥好說的,一般求路徑的問題就是要用dfs,可是不需要求所有的到達路徑,也不需要求隨意的一條到達路徑,不然dfs準沒錯。所以我們還是要用bfs,不過在bfs的時候,把經過的所有節點都求出從開始到他這...
126 單詞接龍 II
給定兩個單詞 beginword 和 endword 和乙個字典 wordlist,找出所有從 beginword 到 endword 的最短轉換序列。轉換需遵循如下規則 每次轉換只能改變乙個字母。轉換過程中的中間單詞必須是字典中的單詞。說明 如果不存在這樣的轉換序列,返回乙個空列表。所有單詞具有相...