LeetCode題解:127. 單詞接龍,雙向BFS,JavaScript,詳細註釋
原題連結:https://leetcode-cn.com/problems/word-ladder/
解題思路:
- 分別以beginWord和endWord為起點,分別向中間推進,當兩者相遇時,即為找到了最短路徑。
- 每次推進都選取兩端佇列中較小者,能夠優化遍歷的次數。
- BFS需要使用佇列,當一端佇列元素的下一個變化單詞存在於另一端的佇列中時,即可認為兩者相遇。
- 使用Map判斷單詞是否存在於佇列中,可以進一步優化速度。因此可以在每次遍歷佇列前,都將另一端的佇列轉換為Map。
- 需要注意的測試用例:
"ymain"
"oecij"
["ymann","yycrj","oecij","ymcnj","yzcrj","yycij","xecij","yecij","ymanj","yzcnj","ymain"]
/**
* @param {string} beginWord
* @param {string} endWord
* @param {string[]} wordList
* @return {number}
*/
var ladderLength = function (beginWord, endWord, wordList) {
// 每次都遍歷佇列,初始時存入beginWord,對應層級為1
let queue = [[beginWord, 1]];
// 雖然兩端的遍歷都需要使用佇列,實際操作時可以用Map來加速判斷是否相遇的過程
// 每次遍歷時,只需要取queue和map中長度較小的一個,將其轉換為一個佇列進行遍歷即可
let map = new Map([[endWord, 1]]);
// 使用Set判斷wordList中的單詞是否被使用過
let wordSet = new Set(wordList);
// 由於雙向BFS即使endWord不存在於wordList中,也有可能會相遇
// 因此要先判斷wordList中是否有endWord,若不存在則表示無法轉換
if (!wordSet.has(endWord)) {
return 0;
}
// 如果queue和map中任意一個被清空,表示雙向BFS不會相遇,即為無法進行轉換
while (queue.length && map.size) {
// 選取queue和map中較短的一個進行遍歷,優化搜尋速度
if (queue.length > map.size) {
// 將queue和map對調,保證每次遍歷的都是queue
[queue, map] = [Array.from(map), new Map(queue)];
}
// 將queue中元素出隊,搜尋下一個轉換的單詞
const [word, level] = queue.shift();
// 遍歷當前單詞的每個字元
for (let i = 0; i < word.length; i++) {
// 生成a-z的字元
for (let j = 97; j < 123; j++) {
// 以單詞hit為例,此處生成的是該單詞中每個字母所有可能變化情況
// 即為*it、h*t、hi*,*號可被a-z替代
const newWord =
word.slice(0, i) + String.fromCharCode(j) + word.slice(i + 1);
// 如果newWord在map中存在,表示雙向BFS相遇,即為找到了最短序列
if (map.has(newWord)) {
// 將兩端的level想加,即為總長度
return map.get(newWord) + level;
}
// 如果newWord存在於wordList中,表示newWord可作為下一個轉換單詞
if (wordSet.has(newWord)) {
// 將newWord從wordList中刪除,避免重複使用
wordSet.delete(newWord);
// 將newWord入隊,進行下一層搜尋,同時層級加一
queue.push([newWord, level + 1]);
}
}
}
}
// 如果推出迴圈,表示未找到轉換序列,返回0
return 0;
};
相關文章
- 【LeetCode】127. 單詞接龍LeetCode
- leetcode 127. 單詞接龍(C++)LeetCodeC++
- 單詞接龍---快速建圖----雙向BFS(廣度優先遍歷)
- LeetCode題解:641. 設計迴圈雙端佇列,使用佇列,JavaScript,詳細註釋LeetCode佇列JavaScript
- LeetCode題解:264. 醜數 II,二叉堆,JavaScript,詳細註釋LeetCodeJavaScript
- JavaScript註釋:單行註釋和多行註釋詳解JavaScript
- leetcode刷題之1160拼寫單詞 java題解(超詳細)LeetCodeJava
- LeetCode題解:劍指 Offer 40. 最小的k個數,二叉堆,JavaScript,詳細註釋LeetCodeJavaScript
- JavaScript物件導向名詞詳解JavaScript物件
- P1019 單詞接龍(dfs)
- 160行程式碼仿Vue實現極簡雙向繫結[詳細註釋]行程Vue
- [LeetCode題解]79. 單詞搜尋LeetCode
- Leetcode:2. 兩數相加(C++帶詳細註釋)LeetCodeC++
- O(nlogn)快速排序-雙路排序+詳細註解排序
- [LeetCode] 最短的橋 雙BFS JavaLeetCodeJava
- springboot介面接參註解詳解Spring Boot
- 洛谷題單指南-搜尋-P1019 [NOIP2000 提高組] 單詞接龍
- CF995E Number Clicker (雙向BFS)
- LeetCode題解(0692):前K個高頻單詞(Python)LeetCodePython
- SpringBoot註解大全(詳細)Spring Boot
- Databinding 雙向繫結詳解
- Tarjan演算法及其應用 總結+詳細講解+詳細程式碼註釋演算法
- LeetCode題解(0407):接雨水II(Python)LeetCodePython
- Java註解最全詳解(超級詳細)Java
- 註解的詳細介紹
- JavaScript物件導向詳解(原理)JavaScript物件
- SpringBoot註解最全詳解(整合超詳細版本)Spring Boot
- LeetCode 單詞拆分LeetCode
- Leetcode 239. 滑動視窗最大值 (Java實現 超詳細註釋!)LeetCodeJava
- Servlet、HTTP詳細解釋!ServletHTTP
- JPS 命令詳細解釋
- Element-ui(更新中表單最詳細的解釋)UI
- JavaScript 註釋JavaScript
- 「轉」Laravel 依賴注入原理(詳細註釋)Laravel依賴注入
- Bootstrap的Model原始碼詳細註釋 (轉)boot原始碼
- Spring @Conditional註解 詳細講解及示例Spring
- Application.Caller詳細解釋APP
- LeetCode BFS題目以及要注意的點LeetCode