127. 单词接龙
字典 wordList 中从单词 beginWord **和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk:
- 每一对相邻的单词只差一个字母。
- 对于
1 <= i <= k时,每个si都在wordList中。注意,beginWord**不需要在wordList中。 sk == endWord
给你两个单词 **beginWord **和 endWord 和一个字典 wordList ,返回 从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0 。
示例 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 <= beginWord.length <= 10endWord.length == beginWord.length1 <= wordList.length <= 5000wordList[i].length == beginWord.lengthbeginWord、endWord和wordList[i]由小写英文字母组成beginWord != endWordwordList中的所有字符串 互不相同
/**
* @param {string} beginWord
* @param {string} endWord
* @param {string[]} wordList
* @return {number}
*/
var ladderLength = function(beginWord, endWord, wordList) {
const wordSet = new Set(wordList); // 词典集合
// 词典中不存在要最终转换的单词,直接返回0
if (!wordSet.has(endWord)) {
return 0;
}
// 队列的每项维护一个二元组 [单词, 层数]
const queue = [[beginWord, 0]];
while (queue.length) {
// 队首出队
const [word, h] = queue.shift();
if (word === endWord) {
return h + 1;
} else {
// 继续找下一层
for (const w of wordSet) {
if (isDiffOne(word, w)) {
queue.push([w, h + 1]);
wordSet.delete(w);
}
}
}
}
return 0;
};
function isDiffOne(word1, word2) {
const len = word1.length;
let diffSum = 0;
for (let i = 0; i < len; i++) {
if (word1[i] !== word2[i]) {
diffSum++;
if (diffSum > 1) {
return false;
}
}
}
if (diffSum === 1) {
return true;
}
return false;
}