字符串(二)-- LC[17] 电话号码的字母组合

1 电话号码的字母组合

1.1 题目描述

        题目链接:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/

1.2 回溯解法

        这道题的解法是用回溯的方式,在循环里面套了递归调用。本来递归就不好理解了,再加上循环的递归,就更难理解了。 我们先不考虑递归,先看看下面这个问题怎么解决。 假设输入是2,只有一个字符,那么应该怎么解呢? 按照题目要求2=“abc",所以结果应该是["a","b","c"]先不用想着怎么去写递归,只思考下怎么打印出这个结果。 这个太简单了,一个循环就搞定了:

result = []
for ch in "abc":
    result.append(ch)
return result

        上面是伪代码,一个循环就搞定了。 如果输入的是23,应该怎么做呢?23的结果是["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"],我们仍然不考虑怎么去写递归,只是考虑怎么把这个结果给弄出来。代码如下:

result = []
for ch1 in "abc":
    for ch2 in "def":
        result.append(ch1+ch2)
return result

        也就是说23这样的长度为2的字符串可以用两层循环搞定。 如果输入的是234呢,仍然不要考虑怎么去写递归,而是想怎么把结果打印出来。

result = []
for ch1 in "abc":
    for ch2 in "def":
        for ch3 in "ghi":
            result.append(ch1+ch2+ch3)
return result

        这次用了三层循环。 如果输入的是2345,那么代码可以这么写:

result = []
for ch1 in "abc":
    for ch2 in "def":
        for ch3 in "ghi":
            for ch4 in "jkl":
                result.append(ch1+ch2+ch3+ch4)
return result

        这次是用了四层循环。现在是不是能看出一些门道了?对的。循环的嵌套层数,就是输入的字符串长度。输入的字符串长度是1,循环只有1层。 输入的字符串长度是3,循环就是3层。如果输入的字符串长度是10,那么循环就是10层。 可是输入的字符串长度是不固定的,对应的循环的嵌套层数也是不固定的,那这种情况怎么解决呢?这时候递归就派上用场了。

        对于打印"2345"这样的字符串: 第一次递归就是上图中最下面的方格,然后处理完第一个字符2之后,将输入的字符改变成"345"并调用第二个递归函数 第二次递归处理3,将字符串改变成"45"后再次递归 第三次递归处理4,将字符串改变成"5"后继续递归 第四次递归处理5,将字符串改变成""后继续递归 最后发现字符串为空了,将结果放到列表中并返回 上面是从函数调用的角度去看的,而每次调用下一层递归时,都需要将本层的一些处理结果放到一个临时变量中,再传递给下一层,从这个变量层层传递的变化看,就像一棵树一样,这个算法的时间复杂度很高,是 O ( 3 n ) O(3^n) O(3n) 这个级别的,空间复杂度是 O ( n ) O(n) O(n)

        动图如下:

class Solution(object):
	def letterCombinations(self, digits):
		"""
		:type digits: str
		:rtype: List[str]
		"""
		# 注意边界条件
		if not digits:
			return []
		# 一个映射表,第二个位置是"abc“,第三个位置是"def"。。。
		# 这里也可以用map,用数组可以更节省点内存
		d = [" ","*","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]
		# 最终输出结果的list
		res = []
		
		# 递归函数
		def backtrack(tmp, index):
			# 递归的终止条件,注意这里的终止条件看上去跟动态演示图有些不同,主要是做了点优化
			# 动态图中是每次截取字符串的一部分,"234",变成"23",再变成"3",最后变成"",这样性能不佳
			# 而用index记录每次遍历到字符串的位置,这样性能更好
			if index==len(digits):
				res.append(tmp)
				return
			# 获取index位置的字符,假设输入的字符是"234"
			# 第一次递归时index为0所以c=2,第二次index为1所以c=3,第三次c=4
			# subString每次都会生成新的字符串,而index则是取当前的一个字符,所以效率更高一点
			c = digits[index]
			# map_string的下表是从0开始一直到9, ord(c)-48 是获取c的ASCII码然后-48, 48是0的ASCII
			# 比如c=2时候,2-'0',获取下标为2, letter_map[2]就是"abc"
			letters = d[ord(c)-48]
			
			# 遍历字符串,比如第一次得到的是2,页就是遍历"abc"
			for i in letters:
				# 调用下一层递归,用文字很难描述,请配合动态图理解
				backtrack(tmp+i, index+1)
		backtrack("", 0)
		return res

1.3 队列

        我们也可以使用队列,先将输入的 digits 中第一个数字对应的每一个字母入队,然后将出队的元素与第二个数字对应的每一个字母组合后入队…直到遍历到 digits 的结尾。最后队列中的元素就是所求结果。

class Solution(object):
	def letterCombinations(self, digits):
		"""
		:type digits: str
		:rtype: List[str]
		"""	
		if not digits:
			return []
		# 一个映射表,第二个位置是"abc“,第三个位置是"def"。。。
		# 这里也可以用map,用数组可以更节省点内存
		d = [" ","*","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]
		# 先往队列中加入一个空字符
		res = [""]
		for i in digits:
			size = len(res)
			# 由当前遍历到的字符,取字典表中查找对应的字符串
			letters = d[ord(i)-48]
			# 计算出队列长度后,将队列中的每个元素挨个拿出来
			for _ in xrange(size):
				# 每次都从队列中拿出第一个元素
				tmp = res.pop(0)
				# 然后跟"def"这样的字符串拼接,并再次放到队列中
				for j in letters:
					res.append(tmp+j)
		return res

参考

  • 通俗易懂+动画演示 17. 电话号码的字母组合:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/solutions/44182/tong-su-yi-dong-dong-hua-yan-shi-17-dian-hua-hao-m/
  • 回溯+队列 图解:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/solution/hui-su-dui-lie-tu-jie-by-ml-zimingmeng/

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vision Pro 自己写的一些自定义工具(c#)

目录前言一、保存图片工具1、展示2、源码下载地址二、3D图片格式转化1、展示2、源码下载地址三、所有工具汇总下载地址前言 自己用c#写的一些visionPro自定义工具,便于使用的时候直接拿出来,后续会不断添加新的工具。 想看怎么使用c#写visionPro自定义…

深入探究PyTorch:理解PyTorch的基础知识(一)

❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博…

大数据学完好就业么

Python的普及与数据挖掘、人工智能和数值计算等领域的蓬勃发展相关,但同时也与普遍编程需求的增加有关。 Python应用领域广泛,意味着选择Python的同学在学成之后可选择的就业领域有很多,加上Python本身的优势,致使现在越来越多的…

Typora 修改表格宽度

Typora 修改表格宽度 1. 调整模式 2. 设置宽度 <span style"display:inline-block;width: 80px"> 列名 </span>

PUSCH接收端处理流程学习

1. PUSCH 接收端处理流程图 整个接收端处理分出两部分&#xff1a;符号级处理和比特级处理。 2. 符号级处理 2.1 解基带信号 解基带信号包括两个操作&#xff1a;去CP与FFT变换。在发送端时&#xff0c;发送的数据经过基带信号生成时做IFFT变换后添加CP&#xff0c;再通过相…

GPT-4零失误通关大厂模拟面试,offer拿到手软?与AGI首次接触

来源: FoxyearMeta “GPT-4可被视作AGI &#xff08;通用人工智能&#xff09;的早期版本。” 如若从他人口中说出&#xff0c;或许是无稽之谈—— 但是由微软雷蒙德研究院机器学习理论组负责人万引大神Sbastien Bubeck与2023新视野数学奖得主Ronen Eldan、2023新晋斯隆研究奖得…

学习HM微博项目第1天

步骤&#xff1a;搭建基本环境 -> 展示子控制器 -> 项目分层 -> 增加导航功能 -> 增加导航栏按钮。 搭建基本环境该项目使用代码搭建UI界面&#xff0c;所以在HMAppDelegate的didFinishLaunchingWithOptions方法中要创建窗口window并设置窗口的根控制器&#xff0c…

C++特殊类设计

目录 1.请设计一个类&#xff0c;不能被拷贝 2. 请设计一个类&#xff0c;只能在堆上创建对象 3. 请设计一个类&#xff0c;只能在栈上创建对象 4. 请设计一个类&#xff0c;不能被继承 5. 请设计一个类&#xff0c;只能创建一个对象(单例模式&#xff09; 1.请设计一个类&…

Go语言精修(尚硅谷笔记)第十六章

十六、goroutine和channel 16.1 goroutine线程-基本介绍 进程就是程序在操作系统中的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位线程是进程的一个执行实例&#xff0c;是程序执行的最小单元&#xff0c;它是比进程更小的能独立运行的基本单位一个进程可以创…

ChatGPT来了,让我们快速做个AI应用

你好&#xff0c;我是徐文浩。 过去的两讲&#xff0c;我带着你通过OpenAI提供的Embedding接口&#xff0c;完成了文本分类的功能。那么&#xff0c;这一讲里&#xff0c;我们重新回到Completion接口。而且这一讲里&#xff0c;我们还会快速搭建出一个有界面的聊天机器人来给你…

2023最新 淘宝短视频运营新思路!

为了增加用户在淘内的停留时长&#xff0c;今年直播与视频&#xff0c;在站内的重要性被进一步提高。对于淘系卖家来说&#xff0c;短视频板块重要的是种草及成交两个板块&#xff1a;● 种草板块&#xff1a; 对于想做种草的店铺来说&#xff0c;提升时长、互动率是重心。针对…

【学习笔记】计算机视觉与深度学习(4.卷积神经网络)

学习视频&#xff1a; 鲁鹏-计算机视觉与深度学习 同系列往期笔记&#xff1a; 【学习笔记】计算机视觉与深度学习(1.线性分类器) 【学习笔记】计算机视觉与深度学习(2.全连接神经网络) 【学习笔记】计算机视觉与深度学习(3.卷积与图像去噪/边缘提取/纹理表示) 1 全连接神经网…

数据结构——红黑树

一、红黑树 1.红黑树的概念 红黑树是一种二叉搜索树&#xff0c;但在其每个节点上增加了一个存储位表示节点的颜色&#xff0c;可以是Red或Black。通过对任何一条从根到叶子的路径上各个节点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出两倍&#xff0c…

2023年非业绩亏损ST股票投资策略研究报告

第一章 ST 股票概况 ST 股票是指中国股市上的一种特殊类型的股票&#xff0c;全称为“特别处理股票”&#xff0c;简称为 ST 股票。1998年4月22日&#xff0c;沪深证券交易所宣布将对财务状况和其他财务状况异常的上市公司的股票交易进行特别处理&#xff0c;由于“特别处理”…

《程序员面试金典(第6版)》面试题 08.04. 幂集(回溯算法,位运算,C++)不断更新

题目描述 幂集。编写一种方法&#xff0c;返回某集合的所有子集。集合中不包含重复的元素。 说明&#xff1a;解集不能包含重复的子集。 示例: 输入&#xff1a; nums [1,2,3] 输出&#xff1a; [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ] 解题思路与代码 其实…

王爽-汇编语言第二版学习-day1

学习日记day1 查看CPU和内存&#xff0c;用机器指令和汇编指令编程 版本&#xff1a;Windows XP 5.1.2006 R命令查看、改变CPU寄存器的内容 CS 0AE1 IP 0100 也就是说&#xff0c;内存0AE1&#xff1a;0100处的指令为CPU当前要读取和执行的指令。并且CS&#xff1a;IP所指…

最强绘图AI:一文搞定Midjourney(附送咒语)

最强绘图AI&#xff1a;一文搞定Midjourney&#xff08;附送咒语&#xff09; Midjourney官网&#xff1a;https://www.midjourney.com 简介 Midjourney是目前效果最棒的AI绘图工具。访问Midjourney需要科学姿势。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下…

MybatisPlus简讲 -- 狂神说JAVA版

MybatisPlus 简讲快速入门配置日志CRUD扩展Insert 插入主键生成策略更新操作自动填充乐观锁查询操作分页查询删除操作逻辑删除性能分析插件条件构造器代码自动生成快速入门 创建数据库 mybatis_plus 创建 user 表 CREATE TABLE user (id BIGINT(20) NOT NULL COMMENT 主键ID,n…

gpt2中文训练教程-gpt2文本生成

ChatGPT是基于GPT模型的智能对话系统&#xff0c;可用于自然语言生成、文本对话、机器翻译等自然语言处理任务。ChatGPT使用了强化学习技术&#xff0c;能够自动调节模型的参数和优化模型的输出&#xff0c;从而实现更加自然和准确的对话效果。 ChatGPT的核心是GPT模型&#xf…

传感器实验讲解1

1.应变片单臂电桥&#xff0c;半桥&#xff0c;全桥性能实验 首先是应变片&#xff0c;这个不再过多讲解&#xff0c;实验所利用的是应变片的电阻应变效应——即金属或半导体在外力作用下&#xff0c;产生应变&#xff0c;其阻值也相应改变。 由于一般产生的应变都是微小的&a…
最新文章