LeetCode算法学习之--DFS&&BFS--127. 单词接龙

176 阅读1分钟

「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战

大家好今天给大家分享下一道 LeetCode 困难度 的题目127. 单词接龙

题目

字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列:

序列中第一个单词是 beginWord 。 序列中最后一个单词是 endWord 。 每次转换只能改变一个字母。 转换过程中的中间单词必须是字典 wordList 中的单词。 给你两个单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。

image.png

分析

1.每次转换只能变化一个字符

2.变化过程中的单词必须属于wordlist中

3.返回从beginword 到 endWord的最短转换次数

解放

1.DFS

2.BFS

解法一:DFS

思路
1.把等待变化的单词都放在beginWordArr中
2.然后进行递归,在递归中进行如下操作
    1.如果starArr为空 则直接返回0
    2.创建next 数组,收集新的满足条件的word
    3.迭代字母从a 到z 
    4.改变word每个位置的值,如果改变后的word就等于了endword 那么直接返回len+1
    5.如果不等于endWord,但是在wordList中,则加入next中,待进行下次递归,下次递归时候把len+1
3.然后返回递归的值
​
*/
​
var ladderLength = function (beginWord, endWord, wordList) {
  const beginWordArr = [beginWord];
  const wordSet = new Set(wordList);
  const cache = new Set();
  if (!wordSet.has(endWord)) return 0;
​
  function recur(startArr, cache, endWord, wordSet, len) {
    if (startArr.length === 0) {
      return 0;
    }
    const next = [];
​
    for (const word of startArr) {
      for (let i = 0; i < word.length; i++) {
        //迭代字母从a 到z
        for (let c = 97; c <= 122; c++) {
          //改变word每个位置的值,
          const newWord =
            word.slice(0, i) + String.fromCharCode(c) + word.slice(i + 1);
          //   word就等于了endword 那么直接返回len+1
          if (newWord === endWord) {
            return len + 1;
          }
          if (cache.has(newWord)) continue;
          //   不等于endWord,但是在wordList中,则加入next中,待进行下次递归
          if (wordSet.has(newWord)) {
            next.push(newWord);
            cache.add(newWord);
          }
        }
      }
    }
​
    // 下次递归时候把len+1
    return recur(next, cache, endWord, wordSet, len + 1);
  }
​
  return recur(beginWordArr, cache, endWord, wordSet, 1);
};
​
/* 复杂度
时间 O(n*c^2) c为单词的长度
空间 O(n*c^2) 
*/

解法二:BFS

思路
1.和DFS相似,只是使用queue来模拟递归栈
2.差异是
 1.每次queue.shift 取出需要len++
 2.每次把新的next推入queue中, 如果next为空则不再加入queue中
*/
var ladderLength = function (beginWord, endWord, wordList) {
  const beginWordArr = [beginWord];
  const wordSet = new Set(wordList);
  const cache = new Set();
  if (!wordSet.has(endWord)) return 0;
  const queue = [beginWordArr];
  let len = 1;
​
  while (queue.length) {
    const beginWordArr = queue.shift();
    len++;
    const next = [];
​
    for (const word of beginWordArr) {
      for (let i = 0; i < word.length; i++) {
        //循环单词列表
        for (let c = 97; c <= 122; c++) {
          //循环26个小写字符
          //得到新的单词
          const newWord =
            word.slice(0, i) + String.fromCharCode(c) + word.slice(i + 1);
          if (newWord === endWord) {
            return len;
          }
          if (cache.has(newWord)) continue;
          if (wordSet.has(newWord)) {
            next.push(newWord);
            cache.add(newWord);
          }
        }
      }
    }
​
    next.length && queue.push(next);
  }
​
  return 0;
};
​
/* 复杂度
时间 O(n*c^2) c为单词的长度
空间 O(n*c^2) 
*/

总结

今天这道题是主要是练习使用DFS和BFS来求解“基因变化” 和“单词变化类的题目”类似的题目

大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢

大家如果对“TS”感兴趣的可以看看我的专栏 (TypeScript常用知识),感谢大家的支持

文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com