003. 电话号码的字母组合——回溯算法

1.题目链接:

17. 电话号码的字母组合

2.解题思路:

2.1.题目要求:

给定一个仅包含数字 2-9 的字符串 digits ,返回所有它能表示的字母组合。

数字和字母的关系:

例子:

输入:"23"

输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

2.2.思路:

制作成n叉树,比如下图,输入"23",遍历完 2 的字母然后又遍历 3的字母。

2.3.回溯三部曲:

先用二维数组映射数字和字母的关系

const string letterMap[10] = {
    "", // 0
    "", // 1
    "abc", // 2
    "def", // 3
    "ghi", // 4
    "jkl", // 5
    "mno", // 6
    "pqrs", // 7
    "tuv", // 8
    "wxyz", // 9
};

 

2.3.1.确定回溯函数参数

 首先需要一个字符串s来收集叶子节点的结果,然后用一个字符串数组result保存起来,这两个定义为全局变量,可以显的参数简洁一点。

函数的参数写题目传进来的数字字符串 digits ,以及int型的index(代表遍历的层数)

index用于终止条件,作用是统计数字数量,用于终止条件(下面解释)

vector<string> result;
string s;
void backtracking(const string& digits, int index)

 

2.3.2.确定终止条件

终止条件就是当 输入的数字个数(digits.size) 等于 index 遍历的层数后,把字符串 s 搜集到的结果,传入结果集 result。

if (index == digits.size()) {
    result.push_back(s);
    return;
}

 

2.3.3.确定单层遍历逻辑

先将 字符串digits 里的"数字"转成int类型的数字,因为题目给的数字实际上是字符串...需要先进行转化,

用这个数字取上面定义的数字和字母的映射,取出数字对应的字母集,用于for循环(for循环里在按顺序取出字母进行配对)

int digit = digits[index] - '0';        // 将index指向的数字转为int
string letters = letterMap[digit];      // 取数字对应的字符集

 后面就是for循环了,遍历的结果输入储存字符串 s 里面,用于在终止条件触发的时候,输入结果集,同时记得要回溯。

for (int i = 0; i < letters.size(); i++) {
    s.push_back(letters[i]);            // 处理
    backtracking(digits, index + 1);    // 递归,注意index+1,一下层要处理下一个数字了
    s.pop_back();                       // 回溯
}

组合一下:

int digit = digits[index] - '0';        // 将index指向的数字转为int
string letters = letterMap[digit];      // 取数字对应的字符集
for (int i = 0; i < letters.size(); i++) {
    s.push_back(letters[i]);            // 处理
    backtracking(digits, index + 1);    // 递归,注意index+1,一下层要处理下一个数字了
    s.pop_back();                       // 回溯
}

 

2.4.总代码:

// 版本一
class Solution {
private:
    const string letterMap[10] = {
        "", // 0
        "", // 1
        "abc", // 2
        "def", // 3
        "ghi", // 4
        "jkl", // 5
        "mno", // 6
        "pqrs", // 7
        "tuv", // 8
        "wxyz", // 9
    };
public:
    vector<string> result;
    string s;
    void backtracking(const string& digits, int index) {
        if (index == digits.size()) {
            result.push_back(s);
            return;
        }
        int digit = digits[index] - '0';        // 将index指向的数字转为int
        string letters = letterMap[digit];      // 取数字对应的字符集
        for (int i = 0; i < letters.size(); i++) {
            s.push_back(letters[i]);            // 处理
            backtracking(digits, index + 1);    // 递归,注意index+1,一下层要处理下一个数字了
            s.pop_back();                       // 回溯
        }
    }
    vector<string> letterCombinations(string digits) {
        s.clear();
        result.clear();
        if (digits.size() == 0) {
            return result;
        }
        backtracking(digits, 0);
        return result;
    }
};

3.疑问

字符串类型减个字符型的 '0' 就变成int类型的了??

 int digit = digits[index] - '0';

 C++中用数字表示的字符减去字符 '0'的含义是讲该char类型的字符转换为对应的int类型,

例如;

  1. char S = '5';

  2. int X = S - '0';

  3. cout << X << endl;

X的输出结果是:

x:5

index初始值干嘛要取个0?他是干嘛的??

好像他是层数,用于在终止条件上作比较的,加入数字数量是2,初始是0层,递归一次=1,第二次变成=2,这个时候要进行第三次了。在第三次的递归里碰上终止条件,然后返回,嗯,刚好也可以。

4.记录:

无,待会写下代码,

太晚了,没梳理完,代码也只是过,不过进度要紧。也没有那么多完美的事,尽力完善就好

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值