「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」
大家好今天给大家分享下一道 LeetCode 困难度 的题目127. 单词接龙
题目
字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列:
序列中第一个单词是 beginWord 。 序列中最后一个单词是 endWord 。 每次转换只能改变一个字母。 转换过程中的中间单词必须是字典 wordList 中的单词。 给你两个单词 beginWord 和 endWord 和一个字典 wordList ,找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列,返回 0。
分析
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