我正在尝试编写一个算法,该算法应该找到从给定 beginWord 到 endWord 的最短转换路径,这样一次就可以更改一个字母。
测试用例
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
预期输出为5,因为最短转换之一可以跟随其长度为5:
"hit" -> "hot" -> "dot" -> "dog" -> "cog"
在我的算法中,我使用队列跟踪BFS,并且对于每个单词,我将所有字母替换为所有字母,从' a'到' z'在这样做的同时,我检查给定字典中是否存在结果词,即 wordList 。
如果确实如此,那么我将它推入队列,因此它也可以像最后一个字一样进行处理。否则,将从队列中进行下一个条目,依此类推,直到队列为空。
现在,我在下面给出的代码返回hit -> hot -> dot -> lot -> dog -> log -> cog
,这是一个错误的输出。这主要是因为dot
向lot
以及dog
的错误转换。
lot
和dog
以及与dot
不同的一个字母,因此它们都会被推送到队列并稍后处理,这会导致类似{{1}的双重转换问题进入lot
和log
。
现在,这清楚地表明我错过了BFS和最短路径搜寻的一些关键点。我如何确定必须将cog
转换为dot
而不是dog
,以确保我按照最短路径到达预期目标,前提是两者都是有效转换lot
。
这有助于我理解和修复我的代码。
dot
答案 0 :(得分:0)
您可以在转换字符串时执行一些额外的处理以获得正确的输出。在替换字母之前,将要替换的字符(i)
与将其放置的字符(j)
进行比较。
为每次迭代保留一个标志变量flag
,并检查新字符j
是否更接近EndWord
中相应位置的字符。如果它靠近而不是离开(例如,对于cog中的'c','d'对'l')并存在于WordList
中,请进行替换并设置flag = true
。如果距离角色的距离相同也可以进行另一次变换,请检查标志,如果为真,则跳过它,否则进行变换。
希望这有帮助。
答案 1 :(得分:0)
我用所有字母替换每个字母
意味着您进行了太多有效性检查。
我建议您只用有效字母替换每个字母。例如,“hit”中的i只能替换为o:“hot”,“dot”,“dog”,“lot”,“log”,“cog”。
这将使程序更高效,更不容易出错。
答案 2 :(得分:0)
我想我在理解中找到了主要问题。主要问题是在给定的水平,即距离' d'从树的根级,我可以有多个匹配,例如"批号"和#34;狗"通过转换" dot"来达到与它们相同的水平。
在每个级别,我必须耗尽队列,否则我计算的距离将变得不正确。
因此,当我将代码更改为以下代码(请参阅代码中的注释Process all items in queue which contains words on same level
)时,算法变得更好。至少对于许多测试案例更好,包括在这个问题中给出的测试案例。
感谢大家审核代码。 :)
var ladderLength = function(beginWord,endWord,wordList){ wordList = new Set(wordList);
var queue = [], distance = 1, i, j, len;
len = beginWord.length;
queue.push(beginWord);
while (queue.length > 0) {
// Process all items in queue which contains words on same level
for (var k=0; k<queue.length; k++) {
var currentWord = queue.shift();
if (currentWord === endWord) {
return distance;
}
for (i = 0; i < len; i++) {
var tempCh = currentWord[i];
for (j = 'a'; j <= 'z'; j = String.fromCharCode(j.charCodeAt(0)+1)) {
if (j !== tempCh) {
currentWord = currentWord.replaceAt(i,j);
if (wordList.has(currentWord)) {
wordList.delete(currentWord);
queue.push(currentWord);
}
}
}
currentWord = currentWord.replaceAt(i, tempCh);
}
}
distance++;
}
return 0;
};
String.prototype.replaceAt=function(index, replacement) {
return this.substr(0, index) + replacement+ this.substr(index + replacement.length);
}