BFS中队列大小的重要性

问题描述 投票:-1回答:2

我试图在Leetcode上解决以下问题:https://leetcode.com/problems/word-ladder/description/。问题是:

给定两个单词(beginWordendWord)和字典wordList,我们必须找到从beginWordendWord的最短变换序列的长度,这样每个中间单词都在字典中,并且在每一步我们只能改变一个字母。因此,如果beginWord ='hit'和endWord是'cog',而dict有["hot","dot","dog","lot","log","cog"],那么答案就是5

我试图理解高度赞成的解决方案(比我的更好),如下所示:

class Solution {
public:
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {
        wordDict.insert(endWord);
        queue<string> toVisit;
        addNextWords(beginWord, wordDict, toVisit);
        int dist = 2;
        while (!toVisit.empty()) {
            int num = toVisit.size();
            for (int i = 0; i < num; i++) {    //-->why this for loop?
                string word = toVisit.front();
                toVisit.pop();
                if (word == endWord) return dist;
                addNextWords(word, wordDict, toVisit);
            }
            dist++;
        }
    }
private:
    void addNextWords(string word, unordered_set<string>& wordDict, queue<string>& toVisit) {
        wordDict.erase(word);
        for (int p = 0; p < (int)word.length(); p++) {
            char letter = word[p];
            for (int k = 0; k < 26; k++) { 
                word[p] = 'a' + k;
                if (wordDict.find(word) != wordDict.end()) {
                    toVisit.push(word);
                    wordDict.erase(word);
                }
            }
            word[p] = letter;
        } 
    } 
};

我几乎理解了整个解决方案,我不理解迭代toVisit.size()次的背后的直觉。这也不是标准BFS算法的一部分。有人可以指出这个循环背后的直觉 - 它究竟是做什么以及为什么范围(0到1小于队列的大小)?

c++ algorithm breadth-first-search
2个回答
0
投票

存在FOR循环以确保仅在访问来自beginWord的当前dist处的所有单词之后才增加dist。另一个usecase


0
投票

内部for循环从0重复到队列大小的原因是,随着搜索的发展:

  • 新单词被添加到您正在迭代的队列中,
  • 同时,当前单词将从该队列中删除。

此for循环将迭代限制为队列中最初的单词,并确保对队列执行的修改不会影响搜索的当前阶段。

如果你再盯着它看一下,你会看到发生了什么。

class Solution {
public:
    int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) {
        wordDict.insert(endWord);
        queue<string> toVisit;
        addNextWords(beginWord, wordDict, toVisit);
        int dist = 2;
        while (!toVisit.empty()) {
            int num = toVisit.size();
            for (int i = 0; i < num; i++) {
                string word = toVisit.front();
                toVisit.pop();                         // <-- remove from front of queue 
                if (word == endWord) return dist;
                addNextWords(word, wordDict, toVisit); // <-- add to back of queue
            }
            dist++;
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.