将其建模为BFS的直觉

时间:2017-12-26 17:55:56

标签: c++ queue breadth-first-search

我正试图在LeetCode.com上解决这个问题:

  

给定一个数字字符串,返回该数字可能代表的所有可能的字母组合。数字和字符之间的映射就像电话键盘。所以:
  2 - < - > abc,
  3 - < - > def,
  4 - < - > ghi,
  等等...

     

输入:" 23&#34 ;;
  输出:[" ad"," ae"," af"," bd"," be"," bf"," cd"," ce"," cf"]。

高度赞成的解决方案如下:

class Solution {
public:
    vector<string> letterCombinations(string digits) {
        std::vector< string > vec;
        if(digits.length()==0)
            return vec;

        std::queue< std::string > ans;
        std::string mapping[]={"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};

        ans.push("");
        for(int i=0; i<digits.length(); i++)
        {
            int x = (digits[i]-'0');
            while(ans.front().length()==i)
            {
                std::string t=ans.front();
                ans.pop();
                for(int j=0; j<mapping[x].length(); j++)
                {
                    ans.push(t+mapping[x][j]);
                }
            }
        }

        std::string val;
        int size=ans.size();
        for(int i=0; i<size; i++)
        {
            val=ans.front();
            ans.pop();
            vec.push_back(val);
        }
        return vec;
    }
};

我有以下问题:

  1. 将此建模作为BFS问题的直觉是什么? I 考虑它的方式,我会有两个向量,一个持有abc作为元素(全部映射到2 )另一个将def作为元素(全部映射到3),然后简单地使用循环将元素组合为adae等等。但这显然效率低下。那么BFS如何在这里适用并提供帮助呢?
  2. 在while循环的条件中究竟发生了什么 - ans.front().length()==i - 逻辑上,为什么将归纳变量i与队列中的值的长度进行比较?
  3. 谢谢!

1 个答案:

答案 0 :(得分:0)

  

将此建模为BFS背后的直觉是什么

这不是真正的BFS:作者使用队列是没有充分理由的 - 他们也可以使用两个向量 - 一个用于上一代字符串,一个用于当前一代。这将使他们不必检查队列前面项目的长度,即ans.front().length()==i:他们会写while (!priorGen.empty()) ...

  

在while循环的条件下究竟发生了什么......

算法通过&#34;代和#34;生成字符串,在前一代&#34;生成的每个字符串的末尾添加一个新字符。&#34;

  • 第零代是一个空字符串
  • 生成x是从代x-1生成的,方法是将相应数字的一个可能表示附加到代x-1
  • 中每个字符串的末尾

队列包含两代的字符串 - 前一个字符串和当前字符串。来自当前一代的字符串比前一代字符串长一个字符。循环条件确保循环继续,直到我们在前一代中用尽字符串。

以下是使用两个单独的&#34;生成&#34;向量而不是单个队列,代码的其余部分保持不变:

vector<string> letterCombinations(string digits) {
    string mapping[]={"0", "1", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    vector<string> priorGen {""};
    vector<string> currentGen;
    if (!digits.size()) return currentGen;
    for(int i=0 ; i < digits.length() ; i++) {
        int x = (digits[i]-'0');
        while(!priorGen.empty()) {
            string t = priorGen.back();
            priorGen.pop_back();
            for(int j=0 ; j < mapping[x].length() ; j++) {
                currentGen.push_back(t+mapping[x][j]);
            }
        }
        swap(priorGen, currentGen);
    }
    return priorGen;
}