
解题思路:
- 映射关系建立:创建一个哈希表存储数字到字母的映射。
- 递归参数: 给定字符串 digits、结果集 result、当前路径 path、当前位置 start。
- 递归过程:
- 当当前位置 start 等于 digits 长度时,说明已经遍历完 digits,加入结果集。
- 遍历 start 对应的字母集,将当前字母加入临时字符串,递归处理下一个数字。
- 递归返回后,撤销选择(回溯),继续尝试其他可能的字母。
Java代码:
class Solution {
private static final Map<Character, String> phoneMap = new HashMap<>() {{
put('2', "abc");
put('3', "def");
put('4', "ghi");
put('5', "jkl");
put('6', "mno");
put('7', "pqrs");
put('8', "tuv");
put('9', "wxyz");
}};
public List<String> letterCombinations(String digits) {
List<String> result = new ArrayList<>();
if (digits.isEmpty()) return result;
backtrack(digits, result, new StringBuilder(), 0);
return result;
}
private void backtrack(String digits, List<String> result, StringBuilder path, int start) {
if (start == digits.length()) {
result.add(path.toString());
return;
}
char digit = digits.charAt(start);
String letters = phoneMap.get(digit);
for (char letter : letters.toCharArray()) {
path.append(letter);
backtrack(digits, result, path, start + 1);
path.deleteCharAt(path.length() - 1);
}
}
}

复杂度分析:
- 时间复杂度: 每个数字可能对应 3 个或 4 个字母。假设输入字符串长度为 n,其中 m 个数字对应 3 个字母,k 个对应 4 个字母,则总组合数为
3
m
×
4
k
3^m × 4^k
3m×4k。时间复杂度为 O(
3
m
×
4
k
3^m × 4^k
3m×4k)
- 空间复杂度: 递归调用栈的深度最大为输入字符串长度 n,因此空间复杂度为 O(n)。
解题思路:
- 递归参数: 给定整数数组 candidates、剩余和 remain(初始化为给定目标整数 target)、结果集 result、当前路径 path、起始索引 start。
- 递归过程:
- 当当前索引 index 等于 digits 长度时,说明已经遍历完 digits,加入结果集。
- 遍历 index 对应的字母集,将当前字母加入临时字符串,递归处理下一个数字。
- 递归返回后,撤销选择(回溯),继续尝试其他可能的字母。
Java代码:
class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
Arrays.sort(candidates);
backtrack(candidates, target, result, path, 0);
return result;
}
private void backtrack(int[] candidates, int remain, List<List<Integer>> result, List<Integer> path, int start) {
if (remain < 0) {
return;
} else if (remain == 0) {
result.add(new ArrayList<>(path));
} else {
for (int i = start; i < candidates.length; i++) {
if (candidates[i] > remain) break;
path.add(candidates[i]);
backtrack(candidates, remain - candidates[i], result, path, i);
path.removeLast();
}
}
}
}
复杂度分析:
- 时间复杂度: O(S),其中 S 是所有可能解的数目。
- 空间复杂度: O(S * k)(k 为组合平均长度)。主要消耗来自递归调用栈和结果列表。递归深度最大为 target / min(candidates)。