leetcode 17 电话号码的字母组合

题目描述:

        给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按任意顺序返回。

        给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

leetcode 17 电话号码的字母组合_第1张图片

思路:

从示例上来说,输入"23",最直接的想法就是两层for循环遍历,正好把组合的情况都输出了。

如果输入"233"呢,那么就三层for循环,如果"2333"呢,就四层for循环.......

理解本题后,要解决如下三个问题:

  • 数字和字母如何映射
  • 两个字母就两个for循环,三个字符就三个for循环,以此类推,然后发现代码根本写不出来
  • 输入1 * #按键等等异常情况

leetcode 17 电话号码的字母组合_第2张图片

代码: 

class Solution {
    //先将数字对应字符串存入数组(直接定义成成员变量即可)
    string arr[10] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};

public:
    //digists数字字符串的长度就是递归的深度,每个数字所对应的字符串str的长度代表递归的广度,i标志着当前层数即递归深度
    //combinStr是一种字母组合,retSV返回字符组合数组
    void _letterCombinations(string& digits, size_t i, string combinStr, vector& retSV) 
    {
        //i等于数字字符串长度时,表示当前递归结束
        if (i == digits.size()) 
        { 
            //此时一种字母组合已经形成,将其插入返回数组中
            retSV.push_back(combinStr); 
            return;
        }
        //取出当前数字(当前层)对应的字符串"abc", "def", "jkl" 等
        string str = arr[digits[i] - '0'];  
   
       	//循环控制宽度,递归控制深度
        //j用于遍历所在层字符串的字符
        for (size_t j = 0; j < str.size(); ++j) 
        {
            //i控制递归遍历的深度,也就是层数
            _letterCombinations(digits, i + 1, combinStr + str[j], retSV);

            /* 
            combinStr+str[j] 将当前层遍历到的单个字母插入字符串,i+1 将递归深度+1进入下一层,即访问下一个数字的字符串
            combinStr不可使用+=,回溯到同一层时,combStr传值调用,combStr不可被改变,因为combStr还要和其他字母组合
            i也不可以使用++,因为递归之后要回溯到上一层,有循环存在,还要在进行下一路的递归,此时必须保证i还是这一层的i
            插一个字母进入下一层,直到最后一层结束再向上回溯,conbinStr也就插入了不同层字母,得到多个数字字母组合 
            */

        }
    }
    vector letterCombinations(string digits) {
        string combinStr;    //组合字符串
        vector retSV;    //收集字符组合的返回值数组
        if (digits.empty()) 
        {
            return retSV;
        }
        _letterCombinations(digits, 0, combinStr, retSV);   //调用递归子函数
        return retSV;
    }
};

你可能感兴趣的:(刷题,leetcode,算法)