leetcode中等oj题:17电话号码字母组合(有关vector、回溯)

题目

链接

  • https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/submissions/

题干

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
题目详情(截自力扣官网)


分析

  1. 映射:把输入数字字符串,映射上按键的每组字母
  2. 回溯:相当于把所有的可能性都遍历了一遍,并返回。
    • 若题目明确告知在n个数中1~3个数字(数目较小)组合的可能性,这种情况可考虑for循环嵌套(但也不建议)
    • 而如题,不确定for循环要嵌套几次,所以往递归方向思考。
    • (我做着题是刚学vector用于练手熟悉的,之前也没不知道回溯,而后通过这个up主讲解学习了,大家也可以适当参考下https://www.bilibili.com/video/BV1cy4y167mM/)
  3. 利用vector存放结果
  4. 重心部分在于:外层for循环横向遍历,内层递归完成纵向遍历。
  5. 具体分析我写在代码旁注释里了

具体代码

主体

class Solution {
    //确定一一对应关系(对应映射若放自己编译器中测试通不过,也可以放在全局中)
    const char* numToStr[10] = { "","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz" };//两种写法都可以,vs19中检查严格测试要const
    //两种都可以,但建议char,此处string还需要额外构造
    //string numToStr[10] = { "","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz" };//本质是在初始化列表的时候,用缺省值初始化

public:
    void Combine(string digits, int di, vector<string>& retV, string combineStr)
    //  参数解释:传入数字字符串,第几层(初次传入0),最后存正解的vector,存上一层for循环(如ad与tuv组合,ad就是combineStr)(初始化默认空)
    {
        if (di == digits.size())//di对比每组数字字符串长度(3 or 4个)
        {
            retV.push_back(combineStr);//每合成一个组合,就push到retV中
            return;
        }
      
        int num = digits[di] - '0';
        string str = numToStr[num];//取到数字对应的字符串
       
       //外框的for循环完成横向遍历
        for (auto ch : str)//把数字对应的字母一一拆分开-->每排的字母串按照for循环一一参与排列
        {
        	//内层的递归完成纵向遍历
            //往第一个数字字符串对应的第二个字母进行递归(依次如此)
            //若使用+=会影响横向的for循环,使之每层叠加,如最后输出:ad t,ad tu,ad tuv,ade t,ade tu,ade tuv,
            Combine(digits, di + 1, retV, combineStr + ch);
         }
    }

    //若递归调用自己,参数和返回值受限于oj平台设置的(只有string digits),没办法控制,故上方给一个子函数,来进行递归
    vector<string> letterCombinations(string digits) {
        vector<string> v;
        if (digits.empty())//判断若为空,就返回空的串
            return v;

        string str;
        Combine(digits, 0, v, str);

        return v;
    }
};

测试

  • 在VS2019中测试是由于检查有点严格,const char* numToStr[10] 要记得加上const
int main()
{
    Solution().letterCombinations("239");
    return 0;
}

回溯算法的模板框架

  • 他人对回溯这类问题的一个大体框架总结,可以大方向这么认识并运用在后续其他类似题上
void backtracking(参数) {
	if (终止条件) {
		存放结果;
		return;
	}
	for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
		处理节点;
		backtracking(路径,选择列表); // 递归
		回溯,撤销处理结果
	}
}


祝大家学习愉快 : )

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值