返回
如何用 JavaScript 解决 LeetCode 题解 127. 单词接龙难题
前端
2023-10-05 05:38:21
1. 问题
在 LeetCode 题解 127. 单词接龙难题中,给你两个单词 beginWord
与 endWord
,以及一个字典 wordList
。设计一个算法,找出从 beginWord
到 endWord
的最短转换序列。
转换规则如下:
- 每次转换只能改变一个字母。
- 转换过程中的中间单词必须是字典
wordList
中的单词。
如果不存在这样的转换序列,则返回 0。
2. 算法思路
为了解决这个问题,我们可以使用广度优先搜索 (BFS) 算法。具体思路如下:
- 将
beginWord
加入队列并将其标记为已访问。 - 从队列中取出一个单词,并尝试生成所有可能的新单词。
- 对于每个新单词,检查它是否在
wordList
中,如果在,则将其加入队列并标记为已访问。 - 重复步骤 2 和 3,直到找到
endWord
。 - 如果队列为空,则说明没有找到
endWord
,返回 0。
3. JavaScript 实现
/**
* LeetCode 题解 127. 单词接龙
*
* @param {string} beginWord 起始单词
* @param {string} endWord 目标单词
* @param {string[]} wordList 词汇表
* @return {number} 最短转换长度
*/
const ladderLength = (beginWord, endWord, wordList) => {
// 检查目标单词是否存在于词汇表中
if (!wordList.includes(endWord)) {
return 0;
}
// 将起始单词加入队列并标记为已访问
const queue = [[beginWord, 1]];
const visited = new Set([beginWord]);
// BFS 循环
while (queue.length > 0) {
const [currentWord, currentLength] = queue.shift();
// 生成所有可能的新单词
const newWords = generateNewWords(currentWord);
// 遍历新单词
for (const newWord of newWords) {
// 检查新单词是否在词汇表中
if (wordList.includes(newWord)) {
// 检查新单词是否为目标单词
if (newWord === endWord) {
return currentLength + 1;
}
// 将新单词加入队列并标记为已访问
if (!visited.has(newWord)) {
queue.push([newWord, currentLength + 1]);
visited.add(newWord);
}
}
}
}
// 队列为空,说明没有找到目标单词
return 0;
};
/**
* 生成所有可能的新单词
*
* @param {string} word 当前单词
* @return {string[]} 所有可能的新单词
*/
const generateNewWords = (word) => {
const newWords = [];
// 遍历单词中的每个字母
for (let i = 0; i < word.length; i++) {
// 替换当前字母
for (let j = 0; j < 26; j++) {
const newWord = word.substring(0, i) + String.fromCharCode(97 + j) + word.substring(i + 1);
// 检查新单词是否有效
if (newWord !== word && !newWords.includes(newWord)) {
newWords.push(newWord);
}
}
}
return newWords;
};
4. 复杂度分析
- 时间复杂度:O(n * m * k),其中 n 是
wordList
的长度,m 是单词的平均长度,k 是字母表的大小。 - 空间复杂度:O(n),用于存储队列和已访问的单词。
5. 总结
这篇文章介绍了如何利用 JavaScript 解决 LeetCode 题解 127. 单词接龙难题。文中结合 BFS 算法与生成所有可能新单词的策略,并辅以丰富的注释和示例代码,帮助读者快速掌握问题的解决思路和具体实现方法。