【LeetCode】17. Letter Combinations of a Phone Number

算法小白,最近刷LeetCode。希望能够结合自己的思考和别人优秀的代码,对题目和解法进行更加清晰详细的解释,供大家参考^_^

Letter Combinations of a Phone Number

Given a digit string, return all possible letter combinations that the number could represent.
A mapping of digit to letters (just like on the telephone buttons) is given below.
这里写图片描述

Input:Digit string "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

Note:
Although the above answer is in lexicographical order, your answer could be in any order you want.

题目大意是:给定一个数字组成的字符串,其中每个数字字符都对应一个字符串,如数字2对应字符串“abc”,数字3对应字符串“def”,其实就是平常使用的九宫格输入法中的对应关系。现在需要按照数字出现的顺序给出所有可能的英文字母组合。

显然,所有的可能组合共计 4^i * 3^(n-i),其中n为输入数字串的长度,i为7和9两个数字出现的次数,n-i即为剩下数字的出现次数。由于1和0并没有对应任何的英文字母,不清楚具体该如何处理,好在实测发现,当字符串中出现1或0时,结果集都为空,这种情况提前处理一下就好了。

第一印象这个题需要用递归的方法,每次递归选取下一个字符串,顺序取出一个字符加到末尾,直到字符长度满足要求,将其加入结果集中,函数返回。

直接上代码:

class Solution {
public:
    // 备选字符串集合,共计8个,坐标0-7分别对应数字字符2-9
    string str_arr[8] = {
        "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"
    };

    // 递归函数,参数较多,是为了方便自己理解,下面一个个解释
    // string str: 每次在该字符串末尾加入字符,直到其长度等于digits的长度
    // const int &len :digits字符串长度,也是最终结果集中每个字符串的长度,这里声明为常量引用
    // const string &digits :输入的数字串,同样声明为常量引用
    // int pos :指定当前递归使用哪个候选集,如pos=2,即使用digits中第3个数字对应的字符串作为候选集
    // vector<string> &vs :结果集,声明为引用 
    void fun(string str, const int &len, const string &digits, int pos, vector<string> &vs){
        if (len == str.length()) vs.push_back(str);  // 长度==len,加入结果集,本次递归结束
        else {
            string tmp = str_arr[digits[pos] - '0' - 2]; // 指定候选集
            ++pos;                                       // 指定下一次使用的数字在digits中的位置  
            for (int i = 0; i < tmp.length(); ++i) {     // 顺序在str的末尾增加一个字符,并递归
                fun(str + tmp[i], len, digits, pos, vs);
            }
        }
    }
    vector<string> letterCombinations(string digits) {
        int len = digits.length();
        vector<string> vs;
        // 处理空串和包含0或1的情况,返回空结果集
        if (0 == len) return vs;
        for (int i = 0; i < len; ++i)
            if (digits[i] == '0' || digits[i] == '1') return vs;

        // 调用递归函数,第一个str为空,pos为0
        fun(string(""), len, digits, 0, vs);
        return vs;
    }
};

我自身对递归程序的编写不是很熟练,5个参数也是我根据一步步的思考加上去的,可能存在冗余,比如pos和len。第一次完成后,也是手动分析了一下递归过程,修改了其中两个主要错误之后,才到上述的样子。

看了别人的代码,也有非递归的方法,暂时先不介绍了,等我回头复习的时候再仔细研究下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值