返回

如何用 JavaScript 解决 LeetCode 题解 127. 单词接龙难题

前端

1. 问题

在 LeetCode 题解 127. 单词接龙难题中,给你两个单词 beginWordendWord,以及一个字典 wordList。设计一个算法,找出从 beginWordendWord 的最短转换序列。

转换规则如下:

  • 每次转换只能改变一个字母。
  • 转换过程中的中间单词必须是字典 wordList 中的单词。

如果不存在这样的转换序列,则返回 0。

2. 算法思路

为了解决这个问题,我们可以使用广度优先搜索 (BFS) 算法。具体思路如下:

  1. beginWord 加入队列并将其标记为已访问。
  2. 从队列中取出一个单词,并尝试生成所有可能的新单词。
  3. 对于每个新单词,检查它是否在 wordList 中,如果在,则将其加入队列并标记为已访问。
  4. 重复步骤 2 和 3,直到找到 endWord
  5. 如果队列为空,则说明没有找到 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 算法与生成所有可能新单词的策略,并辅以丰富的注释和示例代码,帮助读者快速掌握问题的解决思路和具体实现方法。