216.组合总和III
找出所有相加之和为
n的k个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
思路
根据题目意思,依次从 1 到 9 中取数,直到取到 k 个数,如果这 k 个数的和为 n,则找到一个组合,否则,这个组合不是我们的目标。依据该描述,我们使用回溯算法,对每种可能的组合进行遍历。
在每次回溯中,
- 从
[start, 9]中取一个数i后,下一个数在[i + 1, 9]中取得。 - 如果当前组合
path的元素数量为目标n了,判断当前所有元素的和total是否等于n,如果等于,则将这个组合加入到结果集中。 - 如果当前组合中所有元素的和
total大于n,则不用再取值了,当前组合不可能成为目标结果。
代码
class Solution {
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
backTracking(1, n, k, res, path, 0);
return res;
}
private void backTracking(int start, int n, int k, List<List<Integer>> res, List<Integer> path, int total){
if(path.size() == k){
if(total == n){
res.add(new ArrayList<>(path));
}
return;
}
if(total > n){
return;
}
for(int i = start; i <= 9; i++){
path.add(i);
backTracking(i + 1,n,k,res,path,total + i);
path.remove(path.size() - 1);
}
}
}
17.电话号码的字母组合
给定一个仅包含数字
2-9的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
0 <= digits.length <= 4digits[i]是范围['2', '9']的一个数字。
思路
- 为了方便将数字匹配成相应的字母,将其所能对应的字符组成一个字符串,保存在字符串型的数组中。
- 为了让各数字直接对应字符串在数组中的下标,将数组下标为 0 和 1 的字符串设置为空字符串。
- 按照
digits的顺序依次找到匹配的字符串,取字符串中每一个字符都算一种组合方式。回溯树的深度为digits的长度,第index层的宽度为digits[index]对应的字符串的长度。
代码
class Solution {
public List<String> letterCombinations(String digits) {
if(digits.length() == 0){
return new ArrayList<String>();
}
String[] map = new String[]{"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
List<String> res = new ArrayList<>();
StringBuilder lettersCombination = new StringBuilder();
backTracking(map, digits, 0, res, lettersCombination);
return res;
}
private void backTracking(String[] map, String digits ,int index,List<String> res, StringBuilder lettersCombination){
if(index == digits.length()){
// 加入结果集
res.add(new String(lettersCombination.toString()));
return;
}
String mapping = map[digits.charAt(index) - '0'];
for(int i = 0; i < mapping.length(); i++){
lettersCombination.append(mapping.charAt(i));
backTracking(map, digits, index + 1, res, lettersCombination);
lettersCombination.deleteCharAt(lettersCombination.length() - 1);
}
}
}