目录
1.题目描述:
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = "" 输出:[]
示例 3:
输入:digits = "2" 输出:["a","b","c"]
2.算法思路:
-
建立映射表:
- 创建一个数组
map
,其中索引0
和1
为空字符串(因为数字0
和1
不对应任何字母),其余索引2-9
分别对应相应的字母字符串。 - 例如:
map[2] = "abc"
,map[3] = "def"
,依此类推。
- 创建一个数组
-
初始化全局变量:
ans
:用于存储所有可能的字母组合。s
:临时字符串,用于构建当前组合。
-
回溯函数
Backtracking
:- 参数:
digits
:输入的数字字符串。index
:当前处理的数字在digits
中的索引。
- 终止条件:
- 如果
index
等于digits
的长度,说明已经处理完所有数字,将当前组合s
加入ans
并返回。
- 如果
- 递归逻辑:
- 获取当前数字
digits[index]
对应的字母字符串str
。 - 遍历
str
中的每个字母:- 将字母添加到
s
中。 - 递归处理下一个数字(
index + 1
)。 - 回溯:移除
s
的最后一个字母,尝试下一个可能的字母。
- 将字母添加到
- 获取当前数字
- 参数:
-
主函数
letterCombinations
:- 检查输入
digits
是否为空,若为空直接返回空列表。 - 调用
Backtracking
从索引0
开始处理。 - 返回结果
ans
。
- 检查输入
示例流程
以输入 digits = "23"
为例:
- 初始调用
Backtracking("23", 0)
。 - 处理数字
'2'
(str = "abc"
):- 添加
'a'
,递归处理'3'
:- 处理数字
'3'
(str = "def"
):- 添加
'd'
,组合为"ad"
,加入ans
。 - 回溯,移除
'd'
,添加'e'
,组合为"ae"
,加入ans
。 - 回溯,移除
'e'
,添加'f'
,组合为"af"
,加入ans
。
- 添加
- 处理数字
- 回溯,移除
'a'
,添加'b'
,递归处理'3'
:- 类似地,生成
"bd"
,"be"
,"bf"
。
- 类似地,生成
- 回溯,移除
'b'
,添加'c'
,递归处理'3'
:- 生成
"cd"
,"ce"
,"cf"
。
- 生成
- 添加
- 最终
ans = ["ad","ae","af","bd","be","bf","cd","ce","cf"]
。
3.代码展示:
//建立映射表,为了方便对应下标,把第一个和第二个设置为空
const string map[10]{
"","",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz"
};
vector<string>ans;//返回最终的结果
string s;//临时存储
//利用回溯法求解,封装一个函数
void Backtracking(string& digits, int index) {
//终止条件
if (index == digits.size()) {
ans.push_back(s);
return;
}
//获取字符所对应的数字
int num = digits[index] - '0';
//查询映射表
string str = map[num];
//开始遍历
for (int i = 0; i < str.size(); i++) {
s.push_back(str[i]);
//开始递归
Backtracking(digits, index + 1);
//开始回溯,删除最后一个字符
s.pop_back();
}
}
vector<string> letterCombinations(string digits) {
//判断digits是否为空
if (digits.size() == 0) {
return {};
}
Backtracking(digits, 0);
return ans;
}