leetcode刷题精讲————17.电话号码的字母组合

news2025/1/20 10:49:39

力扣icon-default.png?t=MBR7https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/

 

这道题要用到多叉树遍历、回溯、递归、排列组合等相关知识,算是比较经典的例题了,掌握它的核心思想就可以解决这一大类问题。

首先,2~9的数字对应不同的字符串,不同的数字组合也对应不同的字符串组合:

‘2’---> "abc"               '3'--->"def"                  '4'--->"ghi"                        '5;--->"jkl"             '6'--->"mno"               '7'--->"pqrs"                '8'--->"tuv"                        '9'--->"wxyz"

2个数字组合对应字符串中字符个数为2,3对应3....如“234”对应字符串中字符个数为3,有27种排列方式:这种排列方式叫做全排列。

现在清楚了排列规则,我们尝试着解决一下问题。

还是以“234”为例,假设我们拿到该字符串,如何得到它的组合并返回呢?

这就是一个多叉树遍历的过程,并且是深度优先,而非广度优先。

 先从节点a走,到节点d,再往下走到g,碰到结束条件返回上一层回到d,再走另一条路到h,同样碰到结束条件返回到d,再走下一条路到 i,碰到结束条件返回d,此时最下层遍历完毕再返回上一层到a,a再走另一条路e.......就是这么个遍历过程,如此就可以得到所有组合结果。

理论条件具备,下面就是写代码了。刚刚的过程用递归实现会方便一点,非递归实现相对麻烦:

代码如下:

class Solution {
    string _numstr[10] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    void combine(const string& digits,int i,vector<string>& vcombine,string str){
        if(i == digits.size()){
            vcombine.push_back(str);
            return;
        }
        int num = digits[i] - '0';
        string vstr = _numstr[num];
        for(auto e : vstr){
            combine(digits,i+1,vcombine,str+e);
        }
    }
public:
    vector<string> letterCombinations(string digits) {
        vector<string> vcombine;
        if(digits.empty()){
            return vcombine;
        }
        string str;
        int i =0;
        combine(digits,i,vcombine,str);
        return vcombine;
    }
};

 

 

 这里有个问题:最后组合的数组是直接返回给题中给的函数,还是自己创建一个vector<string>把返回的数组传给他?————我选择后者,前者涉及数组合并不太方便,后者创建一个额外的数组可以较好的解决这个问题。

既然要用递归写法,那么一定要理清里面的遍历顺序和终止条件,提前准备好参数。

之前说了,给的数字字符串和对应字母是有映射关系的,我们创建一个string,在里面存好各个数字对应的字母字符串,设定变量 i 对其访问,i 映射数字--->数字映射字母字符串,这样就可以通过digits访问字符串了。i 不能引用传参,因为深度遍历到终止条件会向上返回,i 每次都得重新置为0.

此外还需要一个临时的字符串来接收组合过程中的字符串,初始设置为""空串,并且该字符串不能用引用传参,因为每一次接收字符串后都要回到上一层,不能保留当前字符串结果,否则就不对了。

接下来是递归调用函数,

        for(auto e : vstr){
            combine(digits,i+1,vcombine,str+e);
        }

注意这里 i 不能i++,要用i+1,++改变变量值,会影响递归结果。str+e也是同样的,不能+=,不然每次返回时都要pop前面的串。

终止条件:当递归到最深层时,就返回上一层, i == digits.size()时到达最深处,此时返回return;

注意返回时要将字符串添加保存到我们创建的数组vcombine中,通过push_back实现。

        combine(digits,i,vcombine,str);
        return vcombine;

在外面调用函数,最后返回我们创建的数组(组合形式都在里面了)。

还需要注意一种情况,如果digits是空,那么直接返回空,否则进入函数会push_back一个空串,

答案出现错误,因此记得将该情况独立讨论一下。

 

可能到这里有的小伙伴还不是特别清楚这一过程,那么我再画代码图讲解一下多叉树递归的过程:

 第一层递归:

 第二层递归:

i 不是5,是3写错了.

 i 到达最深处碰到终止条件返回上一层。

 

后续递归过程就和上面一样,一路往最深处走,到达终止条件返回。

其实本题最难的不是这个过程,而是对于条件的判断,什么时候引用返回,什么时候不应该使用等等这些问题是需要思考的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/152112.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JS 安全策略 101

依赖审计 依赖审计其实就是利用 npm 或是 yarn 自带的一个 audit 命令检测 node_module 里存在的一些具有安全隐患的依赖项。我习惯用yarn audit, 所以给大家放了张自己博客的 yarn 审计结果。这里显示&#xff1a;一个叫 trim 的包太老了&#xff0c;有很高的安全风险。 有风…

【数据结构初阶】5. 栈和队列

栈 1.1 栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。**进行数据插入和删除操作的一端 称为栈顶&#xff0c;另一端称为栈底。**栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out&#xff09;的原则…

win7安装onenote2016时碰到30094-1011(0)的 问题

安装办法用途【1】中所有的更新【1】中下载IE11的依赖IE11360软件管家解决OneNote的登录界面不显示问题微软常用运行库360软件管家kernalbase.dll等文件的缺失windowsupdateagent-7.6-x64官网下载Windows6.1-KB4474419-v3-ia64.msu控制面板的update中选择安装支持sha-2校验【3】…

【算法】差分数组

目录1.概述2.代码实现3.应用本文参考&#xff1a; LABULADONG 的算法网站 1.概述 &#xff08;1&#xff09;差分数组的思想与前缀和算法的非常近似&#xff08;有关前置和算法的具体细节可以参考前缀和算法这篇文章&#xff09;&#xff0c;其主要适用于频繁地对原始数组的某…

国产单通道直流有刷马达驱动芯片型号推荐

直流有刷马达驱动芯片是一款适应消费类、工业类的单通道直流有刷驱动IC&#xff0c;适用于各类玩具&#xff0c;智能家居&#xff0c;智能三表。小封装&#xff0c;低功耗&#xff0c;内置完善的保护机制&#xff08;过温/过流/过压&#xff09;。具有一个PWM&#xff08;INA/I…

写了2年文章的我,昨天第一次露脸直播。

作为一名不知名的技术博主&#xff0c;上周六晚上在视频号第一次做露脸直播。 勇敢的迈出视频号开播的第一步&#xff0c;并且数据不错&#xff0c;这个感觉很爽&#xff0c;和写作输出完全是两回事。 写这篇文章的目的是鼓励技术博主们&#xff0c;也尝试一下直播和做视频。 …

ClickHouse 挺快,esProc SPL 更快

开源分析数据库ClickHouse以快著称&#xff0c;真的如此吗&#xff1f;我们通过对比测试来验证一下。 ClickHouse vs Oracle 先用ClickHouse&#xff08;简称CH&#xff09;、Oracle数据库&#xff08;简称ORA&#xff09;一起在相同的软硬件环境下做对比测试。测试基准使用国…

基于ESP8266和SU-03T的离线语音红外遥控器设计

一. 系统设计及框图 之前设计了基于ESP32模块的智能红外遥控器&#xff0c;具体功能见以下CSDN链接&#xff1a; 智能红外遥控器&#xff08;一&#xff09;&#xff1a;功能简介_远望创客学堂的博客-CSDN博客 上面这款智能红外遥控器可以实现红外的远程控制&#xff0c;也可…

【从零开始学习深度学习】44. 图像增广的几种常用方式并使用图像增广训练模型【Pytorch】

大规模数据集是成功应用深度神经网络的前提&#xff0c;图像增广&#xff08;image augmentation&#xff09;技术通过对训练图像做一系列随机改变&#xff0c;来产生相似但又不同的训练样本&#xff0c;从而扩大训练数据集的规模。图像增广的另一种解释是&#xff0c;随机改变…

PCB入门学习—PCB封装的创建2

3.2 IC类PCB封装的创建注&#xff1a;PCB封装的名字一定要和原理图上填写的封装名字一样&#xff0c;不然对不上。规格书里有最大值最小值&#xff0c;就按最大值来做。快捷键EA是特殊粘贴。SOP-8:焊盘比较多时(BGA)可以利用向导去创建。做封装从规格书需要读取的数据&#xff…

19-FreeRTOS 任务通知API

1-xTaskNotifyGive / xTaskNotifyGiveIndexed task.hBaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );BaseType_t xTaskNotifyGiveIndexed( TaskHandle_t xTaskToNotify, UBaseType_t uxIndexToNotify );每个任务都有一组“任务通知” &#xff08;或仅“通知” &a…

Tomcat Connector运行模式

目录 1 Tomcat Connector运行模式 1.1 BIO 模式 1.2 NIO 模式 1.3 APR模式 2 修改Tomcat Connector运行模式为apr 或者解决问题The APR not found 问题 2.1 linux系统 2.2 windows处理 1 Tomcat Connector运行模式 1.1 BIO 模式 BIO模式&#xff08;blocking I/O&am…

[C语言]运用函数指针数组构建一个简单计算器

1.函数指针数组 函数指针数组&#xff0c;即为存放函数首地址的数组&#xff0c;类型为函数指针类型。 2.运用函数指针数组构建简单计算器 1.人机交互&#xff0c;首先要用选择加减或乘除的菜单&#xff0c;再分别写出其功能 void menu() {printf("****************…

嵌入式实时操作系统的设计与开发(五)

线程退出 当线程代码执行完后&#xff0c;系统会隐式地调用acoral_thread_exit()函数进行线程退出相关的操作。 acoral_thread_exit()本质上是要执行acoral_kill_thread()。 void acoral_thread_exit(){acoral_kill_thread(acoral_cur_thread); }void acoral_kill_thread(aco…

ccbill 代码分析

ccbill目录概述需求&#xff1a;设计思路实现思路分析1.BillState2.DBList3.DBListAttr4.DBListDBSrc5.DBListDBSrcsDBListsSurvive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better result,wai…

每日一题:Leetcode59. 螺旋矩阵 II

文章目录 系列&#xff1a;数组专练 语言&#xff1a;java & go 题目来源&#xff1a;Leetcode59. 螺旋矩阵 II 难度&#xff1a;中等 考点&#xff1a;边界问题的处理 & 圈数处理 思路和参考答案文章目录题目描述思路java解法&#xff1a;java参考代码go参考代码&…

OceanBase 4.0解读:从TPC-H性能测评看4.0与3.x差异

关于作者 肖帆 OceanBase技术专家 OceanBase技术专家&#xff0c;开源生态团队成员。毕业于华中科技大学软件工程专业&#xff0c;从事数据库领域的质量保障工作&#xff0c;曾就职于有赞、网易&#xff0c;参与关系型数据库、缓存数据库、对象存储相关产品的测试开发&#x…

.net core api调用webserver接口(详细)

这里废话不多说&#xff0c;我就不简述什么事webserver了&#xff0c;相信点进本博客的大佬都是为了解决问题。 .net core 调用webserver的话还挺简单。首先我们先有个.net core api的项目。 1.我们先注入这个HttpClient 这个内置对象&#xff0c;一会要用到。 // 注入HttpC…

Vue Hook Event 解读

前言 Hook Event (钩子事件)相信很多 Vue 开发者都没有使用过&#xff0c;甚至没听过&#xff0c;毕竟 Vue 官方文档中也没有提及。 Vue 提供了一些生命周期钩子函数&#xff0c;供开发者在特定的逻辑点添加额外的处理逻辑&#xff0c;比如: 在组件挂载阶段提供了beforeMount 和…

代码随想录day34

1005. K 次取反后最大化的数组和 题目 给你一个整数数组 nums 和一个整数 k &#xff0c;按以下方法修改该数组&#xff1a; 选择某个下标 i 并将 nums[i] 替换为 -nums[i] 。 重复这个过程恰好 k 次。可以多次选择同一个下标 i 。 以这种方式修改数组后&#xff0c;返回数…