BFS-127. 单词接龙

98 阅读1分钟

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 <= 10
  • endWord.length == beginWord.length
  • 1 <= wordList.length <= 5000
  • wordList[i].length == beginWord.length
  • beginWordendWord 和 wordList[i] 由小写英文字母组成
  • beginWord != endWord
  • wordList 中的所有字符串 互不相同
/**
 * @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;
}