• 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.回溯三部曲:

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

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

     

    2.3.1.确定回溯函数参数

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

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

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

    1. vector result;
    2. string s;
    3. void backtracking(const string& digits, int index)

     

    2.3.2.确定终止条件

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

    1. if (index == digits.size()) {
    2. result.push_back(s);
    3. return;
    4. }

     

    2.3.3.确定单层遍历逻辑

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

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

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

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

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

    组合一下:

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

     

    2.4.总代码:

    1. // 版本一
    2. class Solution {
    3. private:
    4. const string letterMap[10] = {
    5. "", // 0
    6. "", // 1
    7. "abc", // 2
    8. "def", // 3
    9. "ghi", // 4
    10. "jkl", // 5
    11. "mno", // 6
    12. "pqrs", // 7
    13. "tuv", // 8
    14. "wxyz", // 9
    15. };
    16. public:
    17. vector result;
    18. string s;
    19. void backtracking(const string& digits, int index) {
    20. if (index == digits.size()) {
    21. result.push_back(s);
    22. return;
    23. }
    24. int digit = digits[index] - '0'; // 将index指向的数字转为int
    25. string letters = letterMap[digit]; // 取数字对应的字符集
    26. for (int i = 0; i < letters.size(); i++) {
    27. s.push_back(letters[i]); // 处理
    28. backtracking(digits, index + 1); // 递归,注意index+1,一下层要处理下一个数字了
    29. s.pop_back(); // 回溯
    30. }
    31. }
    32. vector letterCombinations(string digits) {
    33. s.clear();
    34. result.clear();
    35. if (digits.size() == 0) {
    36. return result;
    37. }
    38. backtracking(digits, 0);
    39. return result;
    40. }
    41. };

    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.记录:

    无,待会写下代码,

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

  • 相关阅读:
    【答 疑 记 录】基于 经典全连接神经网络的(cat、dog、panda分类)
    浅记录一下MATLAB安装心得
    C语言实现通讯录
    向excel中导入mysql中的数据表
    NDIR二氧化碳传感器原理介绍
    Java基于SpringBoot的闲一品交易平台
    C-DS二叉树_另一棵树的子树
    Docker Compose
    北理工嵩天Python语言程序设计笔记(7 组合数据类型)
    linux 打开相机工具cheese/guvcview
  • 原文地址:https://blog.csdn.net/qq_70280303/article/details/128080454