力扣:17. 电话号码的字母组合

力扣:17. 电话号码的字母组合

描述

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

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

示例 1:

输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
示例 2:

输入:digits = “”
输出:[]
示例 3:

输入:digits = “2”
输出:[“a”,“b”,“c”]

提示:

0 <= digits.length <= 4
digits[i] 是范围 [‘2’, ‘9’] 的一个数字。

1.递归

排列组合的方式,例如:
题目中的“23”,对应为“abc”,“def”,按下2和3时,能出现的选择,只有“a”,“b”,"c"和“d”,“e”,“f”,然而按下第一个数字2,“a”,“b”,"c"不能互相排列,再次按下数字3,“d”,“e”,“f”可以和前面的“a”,“b”,"c"互相组合,组合的可能就为[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
可按照下面设计代码:
1.创建数组,存储第一个数字对应的字母
2.将第二个数字对应的字母,遍历一遍,一一添加到数组中

#include<iostream>
#include<vector>
using namespace std;
class Solution{
public:string m[10] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};vector<string> letterCombinations(string digits){vector<string> res;for(int i = 0; i < digits.size(); i++){combine(res,digits[i]);}return res;}void combine(vector<string> & res,char ch){int n = res.size();int digit = static_cast<int>(ch)-48;int l = m[digit].size();if(n == 0){//第一个数字对应的字母添加到数组中for(auto j = 0; j < l; ++j){string s(1,m[digit][j]);res.push_back(s);}return;}for(int i = 0; i < n; ++i){//将第二个数字对应的字母,遍历,添加到数组中for(int j = 0; j < l - 1; ++j){res.push_back(res[i] + m[digit][j]);}res[i] += m[digit][l-1];}return;}	
};int main(){Solution solution;string digits = "79";vector<string> result = solution.letterCombinations(digits);cout << "ALL possible combinations for digits " << digits << " are " << endl;for(const string & str:result){cout << str << " ";}cout << endl;return 0;}

在这里插入图片描述

2.队列

先将第一个数字对应的字符入队,之后每次从队头取出一个元素,与m[]中字符串中的未组合的字符分别组合,然后放入队尾。

#include<iostream>
#include<queue>
#include<vector>
#include<map>
using namespace std;
class Solution {
public:vector<string> letterCombinations(string digits) {map<char, string> m = { {'2', "abc"}, {'3', "def"}, {'4', "ghi"}, {'5', "jkl"},{'6', "mno"}, {'7', "pqrs"}, {'8', "tuv"}, {'9', "wxyz"} };std::queue<string> q;vector<string> res;// 先处理第一个数字。是为了使q不为空。for (auto i : m[digits[0]]) {string s(1, i);q.push(s);}  //处理第二个及以后的数字for (auto i = 1; i < digits.size(); ++ i) {int len = q.size();for (auto j = 0; j < len; ++ j) {string s = q.front();		//队首的字符for (auto k = 0; k < m[digits[i]].size(); ++ k) {q.push(s + m[digits[i]][k]);  //队首的字符和余下对应号码未组合的字符组合}q.pop();  //删除队首的字符}}while (!q.empty()) {res.push_back(q.front());q.pop();}return res;}
};int main()
{Solution solution;string digits = "679";vector<string> result = solution.letterCombinations(digits);cout << "All possibile combinations for digits " << digits << " are " << endl;for(const string & str:result){cout << str << " ";}cout << endl;return 0;
}

在这里插入图片描述

3.搜索(深度优先)

3.1

对一个数字对应的字符都搜索(排列)完成后,在进行第二个数字对应的字符搜索(排列),在进行第三个

在这里插入图片描述

和队列的思想类似

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
class Solution{
public:vector<string> letterCombinations(string digits){vector<string>res;if(digits.empty()) return res;vector<string>letter({"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"});string path = "";DFS(digits,0,path,res,letter);return res;}void DFS(string digits, int pos, string & path, vector<string> & res, vector<string> & letter){if(pos == digits.size()){res.push_back(path);return;}for(auto c:letter[digits[pos] - '0']){path.push_back(c);DFS(digits, pos + 1, path, res, letter);path.pop_back();}}
};int main()
{Solution solution;string digits = "679";vector<string> result = solution.letterCombinations(digits);cout << "All possibile combinations for digits " << digits << " are " << endl;for(const string & str:result){cout << str << " ";}cout << endl;return 0;
}

在这里插入图片描述

3.2

每次递归调用时,将新的字符直接添加到 path 的末尾,而不是像之前那样在函数调用之间不断地对 path 进行 push_back 和 pop_back 操作。这种直接在递归调用中更新 path 的方式避免了频繁的操作,简化了代码逻辑。

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
class Solution {
public:vector<string> letterCombinations(string digits) {vector<string>res;if(digits.empty()) return res;vector<string>letter({"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"});string path = "";DFS(digits, 0, path, res, letter);return res;}//此处修改string path,为传值方式void DFS(string digits, int pos, string path, vector<string>& res, vector<string>& letter){if(pos == digits.size()){res.push_back(path);return;}for(auto c: letter[digits[pos] - '0']){DFS(digits, pos + 1, path + c, res, letter);}}
};int main()
{Solution solution;string digits = "679";vector<string> result = solution.letterCombinations(digits);cout << "All possibile combinations for digits " << digits << " are " << endl;for(const string & str:result){cout << str << " ";}cout << endl;return 0;
}

在这里插入图片描述
力扣官方给的解题方法为第三种:

class Solution {
public:vector<string> letterCombinations(string digits) {vector<string> combinations;if (digits.empty()) {return combinations;}unordered_map<char, string> phoneMap{{'2', "abc"},{'3', "def"},{'4', "ghi"},{'5', "jkl"},{'6', "mno"},{'7', "pqrs"},{'8', "tuv"},{'9', "wxyz"}};string combination;backtrack(combinations, phoneMap, digits, 0, combination);return combinations;}void backtrack(vector<string>& combinations, const unordered_map<char, string>& phoneMap, const string& digits, int index, string& combination) {if (index == digits.length()) {combinations.push_back(combination);} else {char digit = digits[index];const string& letters = phoneMap.at(digit);for (const char& letter: letters) {combination.push_back(letter);backtrack(combinations, phoneMap, digits, index + 1, combination);combination.pop_back();}}}
};

力扣:17. 电话号码的字母组合

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

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

相关文章

js中flat(), flatMap()方法

flat() 深度递归遍历数组&#xff0c;并将所有元素与遍历到的子数组中的元素合并为一个新数组返回 用法 const newArr arr.flat(num) const newArr2 [1, 2, 3, [a]].flat()//[1, 2, 3, a]const newArr [1, 2, 3, [a, b, c, [Aa]]].flat(2)//[1,2,3,"a","b&qu…

maven高级教程与父子工程搭建

maven高级教程与父子工程搭建 父子项目搭建 [SpringBoot] 父子项目搭建,过滤多模块发布到私仓 maven继承和传递依赖 maven继承和传递依赖 其他问题 优雅修改多模块maven项目中版本号 解决执行maven命令时提示Process terminated的问题

Linux——文件重定向

目录 前言 一、重定向 二、重定向的运用 三、dup2 四、命令行中的重定向 五、为什么要有标准错误 前言 在之前我们学习了文件标识符&#xff0c;直到close可以使用文件标识符进行关闭&#xff0c;但是当我们关闭1号&#xff08;stdout&#xff09;时&#xff0c;无法往显…

00在linux环境下搭建stm32开发环境

文章目录 前言一、环境搭建1.arm-none-eabi-gcc2.openocd 三、创建stm32标准库工程1.创建工程目录2.修改stm32_flash.ld文件3.写makefile文件4.修改core_cm3.c5.写main函数并下载到板子上 最后 前言 我在那天终于说服自己将系统换成了linux系统了&#xff0c;当换成了linux系统…

如何清除keep-alive缓存

在 Vue.js 中&#xff0c;使用 <keep-alive> 组件可以将组件保留在内存中&#xff0c;以避免重复渲染和销毁&#xff0c;从而提高性能。如果需要手动清除 <keep-alive> 组件的缓存&#xff0c;可以通过两种方法来实现&#xff1a; 通过 $destroy 方法销毁组件&…

UE5.1_使用技巧(常更)

UE5.1_使用技巧&#xff08;常更&#xff09; 1. 清除所有断点 运行时忘记蓝图中的断点可能会出现运行错误的可能&#xff0c;务必运行是排除一切断点&#xff0c;逐个排查也是办法&#xff0c;但是在事件函数多的情况下会很复杂且慢节奏&#xff0c;学会一次性清除所有很有必…

JavaWeb--Mybatis

一&#xff1a;Mybatis概述 1.Mybatis概念 MyBatis 是一款优秀的 持久层框架 &#xff0c;用于简化 JDBC 开发&#xff1b; MyBatis 本是 Apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code&#xff0c;并且改名为 MyB…

OpenTenBase 开发环境搭建及Debug设置

最近有个 OpenTenBase开源核心贡献挑战赛 领导建议大家都去试试&#xff0c;我也去凑了下热闹&#xff0c;发现能力有限一时半会是搞不明白了&#xff0c;最多也就是能搞搞文档翻译&#xff0c;或者写点操作手册啥的。 不过不管怎么样&#xff0c;先把开发环境搭上&#xff0c;…

R语言的数据类型与数据结构:向量、列表、矩阵、数据框及操作方法

R语言的数据类型与数据结构&#xff1a;向量、列表、矩阵、数据框及操作方法 介绍向量列表矩阵数据框 介绍 R语言拥有丰富的数据类型和数据结构&#xff0c;以满足各类数据处理和分析的需求。本文将分享R语言中的数据类型&#xff0c;包括向量、列表、矩阵、数据框等&#xff…

【深度学习模型】6_3 语言模型数据集

注&#xff1a;本文为《动手学深度学习》开源内容&#xff0c;部分标注了个人理解&#xff0c;仅为个人学习记录&#xff0c;无抄袭搬运意图 6.3 语言模型数据集&#xff08;周杰伦专辑歌词&#xff09; 本节将介绍如何预处理一个语言模型数据集&#xff0c;并将其转换成字符级…

vue组件之间通信方式汇总

方式1&#xff1a;props和$emit props和$emit仅仅限制在父子组件中使用 1.props&#xff1a;父组件向子组件传递数据 1.1 代码展示 <template><div><!-- 这是父组件 --><div>父组件中的基本数据类型age的值是:{{this.age}}</div><div>…

giffgaff怎么充值?giffgaff怎么续费?

-性价比高&#xff1a;0月租&#xff0c;免费接收短信&#xff0c;充值一次&#xff0c;接码可以用20年以上&#xff08;仅需半年保号一次&#xff09;&#xff0c;可能是国内性价比最高的接码实体卡&#xff01;-安全&#xff1a;实体卡无须担心因号码被风控&#xff0c;还可以…

springboot+vue,上传图片,回显,以及报错404的问题

最近遇到一个问题&#xff0c;上传图片到服务器以后&#xff0c;回显不了&#xff0c;报错404&#xff1b; 历时三天终于找到解决办法&#xff1a; 1.后端代码&#xff1a; RestController RequestMapping("file") SuppressWarnings({"unchecked","…

面试经典150题【61-70】

文章目录 面试经典150题【61-70】61.旋转链表86.分隔链表104. 二叉树的最大深度100.相同的树226.翻转二叉树101.对称二叉树105.从前序与中序遍历序列构造二叉树106.从后序和中序遍历序列构造二叉树117.填充每个节点的下一个右侧节点指针II114.二叉树展开为链表 面试经典150题【…

留学|谈PS|耶鲁大学管理学院招生办执行主任谈个人PS

仅仅为了共同学习与分享 内容提要:在一篇个人自述中&#xff0c;我们要求申请人将他们的过去和未来有机地结合起来。我们把这种自传叫作“职业目标”自传。它为我们提供了确凿的信息&#xff0c;同时也可以确定申请人是否具有对自己及其职业的综合性反思能力。通常的情况是&am…

PostgreSQL 流复制

文章目录 1.流复制介绍2.异步流复制2.1.主库部署2.2.备库部署2.3.测试 3.同步复制3.1.主库部署3.2.备库部署3.3.测试 4.主备切换 开源中间件 # PostgreSQLhttps://iothub.org.cn/docs/middleware/ https://iothub.org.cn/docs/middleware/postgresql/postgres-stream/1.流复制…

Linux运维_Bash脚本_编译安装Mesa-23.3.6(OpenGL)

Linux运维_Bash脚本_编译安装Mesa-23.3.6(OpenGL) Bash (Bourne Again Shell) 是一个解释器&#xff0c;负责处理 Unix 系统命令行上的命令。它是由 Brian Fox 编写的免费软件&#xff0c;并于 1989 年发布的免费软件&#xff0c;作为 Sh (Bourne Shell) 的替代品。 您可以在…

为什么main方法在Java中代表主线程?

main 方法在 Java 等编程语言中确实代表着程序的入口点&#xff0c;也就是程序开始执行的地方。当我们启动一个 Java 应用程序时&#xff0c;JVM&#xff08;Java 虚拟机&#xff09;会首先查找 main 方法&#xff0c;并从那里开始执行程序。 关于为什么 main 方法代表主线程&a…

unity学习(53)——选择角色界面--分配服务器返回的信息

好久没写客户端了&#xff0c;一上手还不太适应 1.经过测试&#xff0c;成功登陆后&#xff0c;客户端请求list_request&#xff0c;成功返回&#xff0c;如下图&#xff1a; 可见此时model第三个位置的参数是1.也成功返回了所有已注册角色的信息。 2.之前已知创建的角色信息…

141 Linux 系统编程18 ,线程,线程实现原理,ps –Lf 进程 查看

一 线程概念 什么是线程 LWP&#xff1a;light weight process 轻量级的进程&#xff0c;本质仍是进程(在Linux环境下) 进程&#xff1a;独立地址空间&#xff0c;拥有PCB 线程&#xff1a;有独立的PCB&#xff0c;但没有独立的地址空间(共享) 区别&#xff1a;在于是否共…