leetCode 17. 电话号码的字母组合

198 阅读2分钟

记录算法学习,输出更有利于学习!

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母

例子 : 输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]

题目难点:

  1. 返回组合集中的字符串,要与输入字符串长度一致。由此需要对应长度的 for循环层数。
  2. 数字和字母之间的对应关系
  3. 电话号码中 1,#, * 等特殊摁建处理

数字和字母之间的对应关系

可以模拟一个 数组进行对应的映射关系。 const map = ["","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]

对应长度的 for 循环使用 回溯法(递归)

如图:

17.回溯算法图.png

回溯三个步骤:

  • 确定传入的参数。主要是否需要传入 Index ,可以用于枝剪 、去重直接的操作(这道题没用于去重和枝剪等操作)。 主要需要的参数有 : 输入字母的长度 digits.length ,多长就递归多少层,也用于判断是否需要终止递归。 digits。映射对应的字母 index 记录当前是第几个字母
function backtracking(digits, digits.length, index) {}
  • 终止条件。 定义数组去收集结果, 当添加到数组中的字符长度 到达 digits.length 的时候说明已经到达最后一层,需要return
 if(path.length === digits.length) {
	res.push(path.join(""));
	return;     
}
	
  • 单层遍历逻辑。 寻找到输入数字中对应的 字符字符串。然后对这个字符串进行递归循环。
for(const v of map[digits[index]]) {

	path.push(v);
	
	backtracking(digits, digits.length, index + 1);
	
	path.pop();

 }

完整代码

var letterCombinations = function(digits) {

 const k = digits.length;  // 递归的深度 以及 终止条件
 const map = ["","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]; // 映射的数组
 // 特殊情况
 if(!k) return []; 
 if(k === 1) return map[digits].split(""); 

 // 定义一个结果集,一个路径集合
 const res = [], path = [];
 backtracking(digits, k, 0);
 return res;

 function backtracking(n, k, a) {
	 if(path.length === k) {
	 // 当路径集合 和深度一样,说明已经可以组合完成,可以收集
	 res.push(path.join(""));
	 return;
	 }

 for(const v of map[n[a]]) {
	 path.push(v); // 记录循环的字母
	 backtracking(n, k, a + 1);
	 // 回溯,删除当前组合过的数字 如  [a, d] --- [a] 进行下一次循环继续组合
	 path.pop();
	 }
 }
};