题目难度:
Medium
题目要求:
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]
编码思路:(建议对照代码理解)
1.创建最后输出的字符组合的集合combinations;
注:ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
2.如果输入的数字串长度为0,就直接返回,说明为空;
3.创建哈希表,存放数字与字母的对应关系;
4.定义回溯函数,确定传递的参数有【字符组合的集合(combinations),参考的哈希表(phoneMap),给定的数字串(digits),当前数字的位置(index),当前组成的字母组合(combination)】;
5.构造回溯函数:{
(1)如果digits.length()==index,最后一个数字都回溯完了,说明已经是最长的组合,可以将当前的一个字母组合加入combinations合集中,等待返回;
(2)其他情况,以当前数字对应的字母串长度为边界条件,在这个长度内,对所有的字母进行循环,并将其加入当前字母组合的末尾,再回溯进入下一个数字对应的字母串;
}
代码:
/*
* @lc app=leetcode.cn id=17 lang=java
*
* [17] 电话号码的字母组合
*/
// @lc code=start
class Solution {
public List<String> letterCombinations(String digits) {
//创建最后输出的字符组合的集合combinations;
List<String> combinations = new ArrayList<String>();
//如果输入的数字串长度为0,就返回
if(digits.length()==0){
return combinations;
}
//创建哈希表,存放数字与字母的对应关系
Map<Character,String> phoneMap= new HashMap<Character,String>(){{
put('2', "abc");
put('3', "def");
put('4', "ghi");
put('5', "jkl");
put('6', "mno");
put('7', "pqrs");
put('8', "tuv");
put('9', "wxyz");
}};
//定义回溯函数
backtrack(combinations,phoneMap,digits,0,new StringBuffer());
return combinations;
}
//构造回溯函数
public void backtrack(List<String> combinations,Map<Character,String> phoneMap,String digits,int index,StringBuffer combination){
//如果最后一个数字都回溯完了,说明已经是最长的组合,可以加入combinations中,等待返回
if(digits.length()==index){
combinations.add(combination.toString());
}
//
else{
//提取数字串的index位置的数字
char digit=digits.charAt(index);
//利用这个数字从哈希表中,找出对应的字母串
String letters = phoneMap.get(digit);
//以这个字母串的长度为条件进行循环
int lettersCount=letters.length();
//循环
for (int i = 0; i < lettersCount; i++) {
//将这个数字下i位置的字母加入字符串
combination.append(letters.charAt(i));
//回溯下一个数字对应的字母串
backtrack(combinations, phoneMap, digits, index + 1, combination);
//此时,最长的,符合要求的字符串已经加到combinatiions中了,将最后一个数字
combination.deleteCharAt(index);
}
}
}
}
时间复杂度:O(3 ^m × 4 ^n )。m为指定数字字符串中,对应3个字母的个数,n为指定数字字符串中,对应4个字母的个数(包括数字 7、9)。不同的字母组合一共有 3 ^m × 4 ^n 种,需要遍历每一种字母组合。
空间复杂度:O(m+n)。回溯调用m+n次。
补充:****【回溯和递归的区别】:
递归是一种算法,自己调用自己;
回溯是一种算法思想,可以用递归实现,回溯一定有出口(尽头);
可以参考8皇后问题。