回溯算法-leetcode#17-电话号码的字母组合

开启分类模式

class Solution {
public:
    unordered_map> save;
    vector letterCombinations(string digits) {
        vector res;
        if(digits.length()<=0) return res;
        save["2"]=vector({"a","b","c"});
        save["3"]=vector({"d","e","f"});
        save["4"]=vector({"g","h","i"});
        save["5"]=vector({"j","k","l"});
        save["6"]=vector({"m","n","o"});
        save["7"]=vector({"p","q","r","s"});
        save["8"]=vector({"t","u","v"});
        save["9"]=vector({"w","x","y","z"});
        res = com(digits,0);
        return res;
    }
    vector com(string digits,int begin){
        if(begin==digits.size()-1 && save.count(digits.substr(begin,1))) return save[digits.substr(begin,1)];
        if(save.count(digits.substr(begin,digits.length()-begin)))
            return save[digits.substr(begin,digits.length()-begin)];
        string cur=digits.substr(begin,1);
        vector v=save[cur];
        vector aft=com(digits,begin+1);
        vector res;
        for(string i:v){
            for(string j: aft){
                res.push_back(i+j);
            }
        }
        save[digits.substr(begin,digits.length()-begin)]=res;
        return res;
    }
};

看到题目,还是很简单的,大概了解要用递归来做,第一个数字对应的字符串列表*后面字符够成的字符串列表,按个字符切割的话,时间复杂度是(常数C)^n,是常数指数级的,C={3,4}也就是每一个数字代表的字符长度,所以想到用哈希表存下临时结果,可以重复利用已经求解过的子串。定义一个combination函数,输入参数是string和起始下标begin,递归终止条件,如果是最后一个字符,直接从hashmap中查即可返回,如果剩余子串的组合已经求解过,直接从hashmap中查即可返回;否则切割第一个字符和后面子串,后面子串递归求解,两层循环做笛卡尔积,就可以求到所有排列了,在函数返回之前,将当前求解过的结果加入map中。

   这题效果还是不错的,当然也是比较简单吧,总归是个好的开始[捂脸]。

回溯算法-leetcode#17-电话号码的字母组合_第1张图片

你可能感兴趣的:(回溯算法,leetcode)