首页 > 编程语言 >【LeetCode回溯算法#03】电话号码的字母组合(数字映射字母)

【LeetCode回溯算法#03】电话号码的字母组合(数字映射字母)

时间:2023-03-08 23:57:36浏览次数:47  
标签:digits 03 string 映射 index saveStr 字母组合 LeetCode 数字

电话号码的字母组合

力扣题目链接(opens new window)

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

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

17.电话号码的字母组合

示例:

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

说明:尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序

思路

题目给的例子好像可以用for循环解决,但是输入一旦变多,就又碍于for循环的深度限制而无法解决了

所以还是得用回溯

本题与 组合问题 很像,我们要解决的问题如下:

  • 数字和字母之间如何映射?
  • 用回溯解决for循环深度不足的问题,从而遍历出所有组合结果
数字和字母如何映射

可以使用map或者定义一个二维数组,例如:string letterMap[10],来做映射,这里定义一个二维数组,代码如下:

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

1、确定回溯函数的参数与返回值

首先需要一个字符串saveStr来收集叶子节点的结果,然后用一个字符串数组result保存起来,这两个变量依旧定义为全局变量

输入参数是题目给的digits,另外还需要一个参数index,用来指明当前遍历到了digits中的哪个数(index也表示树的深度)

class Solution {
    //定义一个map用来映射数组与字母
private:
    string letterMap[10] = {
        ...
    };
    //确定回溯函数的参数和返回值
    vector<string> res;
    string saveStr;//用于保存叶子结点出的字符串
    void backtracking(string& digits, int index){//index是用来指明当前遍历到了digits中的哪个数        
    }
public:
    vector<string> letterCombinations(string digits) {      
    }
};

2、确定终止条件

index等于输入数字个数就结束,相当于遍历完一遍digits

class Solution {
    //定义一个map用来映射数组与字母
private:
    string letterMap[10] = {
        ...
    };
    //确定回溯函数的参数和返回值
    vector<string> res;
    string saveStr;//用于保存叶子结点出的字符串
    void backtracking(string& digits, int index){//index是用来指明当前遍历到了digits中的哪个数
        //确定终止条件
        if(index == digits.size()){//index等于输入数字个数就结束,即遍历完一遍digits
            res.push_back(saveStr);
            return;
        }        
    }
public:
    vector<string> letterCombinations(string digits) {
    }
};

3、确定单层处理逻辑

首先要取index指向的数字,即从输入数字字符串取数字并转为整型

然后从映射表中取出对应数字的字母映射

class Solution {
    //定义一个map用来映射数组与字母
private:
    string letterMap[10] = {
        "",     //0
        "",     //1
        "abc",  //2
        "def",  //3
        "ghi",  //4
        "jkl",  //5
        "mno",  //6
        "pqrs", //7
        "tuv",  //8
        "wxyz"  //9
    };
    //确定回溯函数的参数和返回值
    vector<string> res;
    string saveStr;//用于保存叶子结点出的字符串
    void backtracking(string& digits, int index){//index是用来指明当前遍历到了digits中的哪个数
        //确定终止条件
        if(index == digits.size()){//index等于输入数字个数就结束,即遍历完一遍digits
            res.push_back(saveStr);
            return;
        }
        //确定单层处理逻辑
        //从输入数字字符串取数字并转为整型
        int singleDigi = digits[index] - '0';
        //从映射表中取出对应数字的字母映射
        string digiMap = letterMap[singleDigi];
        for(int i = 0; i < digiMap.size(); ++i){
            saveStr.push_back(digiMap[i]);
            backtracking(digits, index + 1);
            saveStr.pop_back();//回溯处理
        }
    }
public:
    vector<string> letterCombinations(string digits) {
    }
};

注意这里for循环是从0开始遍历,因为手机按键是从0~9

代码

class Solution {
    //定义一个map用来映射数组与字母
private:
    string letterMap[10] = {
        "",     //0
        "",     //1
        "abc",  //2
        "def",  //3
        "ghi",  //4
        "jkl",  //5
        "mno",  //6
        "pqrs", //7
        "tuv",  //8
        "wxyz"  //9
    };
    //确定回溯函数的参数和返回值
    vector<string> res;
    string saveStr;//用于保存叶子结点出的字符串
    void backtracking(string& digits, int index){//index是用来指明当前遍历到了digits中的哪个数
        //确定终止条件
        if(index == digits.size()){//index等于输入数字个数就结束,即遍历完一遍digits
            res.push_back(saveStr);
            return;
        }
        //确定单层处理逻辑
        //从输入数字字符串取数字并转为整型
        int singleDigi = digits[index] - '0';
        //从映射表中取出对应数字的字母映射
        string digiMap = letterMap[singleDigi];
        for(int i = 0; i < digiMap.size(); ++i){
            saveStr.push_back(digiMap[i]);
            backtracking(digits, index + 1);
            saveStr.pop_back();//回溯处理
        }
    }
public:
    vector<string> letterCombinations(string digits) {
        if(digits == "") return res;
        backtracking(digits, 0);
        return res;
    }
};

注意点

1、数字字符串转为整型的操作

2、TBD

标签:digits,03,string,映射,index,saveStr,字母组合,LeetCode,数字
From: https://www.cnblogs.com/DAYceng/p/17196743.html

相关文章

  • 20230308总结
    总之就是很寄,很寄。T1:想出来前缀和了,但是没想出来怎么优化,于是心态没了,于是就gg了,后面也没想暴力,我很菜。T1可以dfsmndp过nm二分过但是我一个没想出来我很废物......
  • day03-功能实现02
    功能实现02后端:https://github.com/liyuelian/furniture-back-end.git前端:https://github.com/liyuelian/furniture-front-end.git3.功能03-添加家居信息3.1需求分析......
  • 2023、03、08学习总结
    在学页面美化的时候遇到乱码小问题:以下是乱码代码:<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metahttp-equiv="Content-Type"cont......
  • 每日学习总结_20230308
    今天的JavaWeb学习主要集中在Servlet和JSP的使用上。我学习了如何创建一个Servlet并且在Web应用程序中进行部署和调试。同时,我还学习了如何在JSP中使用Java代码,并了解了JSP......
  • LeetCode:Search Algorithm
    LeetCode:SearchAlgorithm1\FirstuniquecharAlgorithmDesign利用字符数量的有限性,通过数组来映射(避免Hash_map的高复杂度)注意数组声明为intA[26]而不是ch......
  • (P03)从C到C++:域运算符,new,delet运算符,重载,name managling与extern “C“,带默认参数的函
    文章目录​​1.域运算符​​​​2.new、delete运算符​​​​3.重载​​​​4.namemanagling与extern“C”​​​​5.带默认形参值的函数​​​​6.带默认形参值的函数的......
  • 【DFS】LeetCode 剑指 Offer 07. 重建二叉树
    题目链接剑指Offer07.重建二叉树思路递归建树,思路与【DFS】LeetCode105.从前序与中序遍历序列构造二叉树相同。代码classSolution{publicTreeNodebuild......
  • [leetcode]2584. 分割数组使乘积互质 (质因数分解)
    题目链接:分割数组使乘积互质思路:指针循环从\([0,len-1)\)每次动态维护指针左边所有数与指针右边所有数质因数交集,第一次交集为0的地方为答案。首先将打表\(10^6\)之内的质......
  • 【栈】LeetCode 剑指 Offer 09. 用两个栈实现队列
    题目链接剑指Offer09.用两个栈实现队列思路两个栈模拟代码classCQueue{Deque<Integer>inStack;Deque<Integer>outStack;publicCQueue(){......
  • 【DP】LeetCode 剑指 Offer 10- I. 斐波那契数列
    题目链接剑指Offer10-I.斐波那契数列思路递推,思路可以参考剑指Offer10-II.青蛙跳台阶问题代码classSolution{publicintfib(intn){inta......