参考资料:
https://programmercarl.com/0216.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8CIII.html
题目描述:
找出所有相加之和为 n
的 k
个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
示例 1:
输入: k = 3, n = 7 输出: [[1,2,4]] 解释: 1 + 2 + 4 = 7 没有其他符合的组合了
思路分析:
使用回溯法:k个数,暴力想法是k重for循环——>涉及多重循环就考虑使用回溯法,回溯法通过递归实习多重for循环
backTracking函数中start下标:在同一个集合中的下标,记录下标,不重复获取元素
剪枝:1.结果已经大于target 2.可获取的元素个数,下标越靠后,可获取的元素越少
代码实现:
class Solution {
List<List<Integer>> result=new ArrayList<>();
LinkedList<Integer> path=new LinkedList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
backTracking(n,k,1,0);//[1,9]
return result;
}
private void backTracking(int target,int k,int start,int sum){
//剪枝
if(sum>target) return;
//终止条件
if(path.size()==k){
if(target==sum){
result.add(new ArrayList<>(path));//
return;
}
}
//单层逻辑
for(int i=start;i<=9-(k-path.size())+1;i++){//剪枝:个数
path.add(i);
sum+=i;
backTracking(target,k,i+1,sum);
//回溯
path.removeLast();
sum-=i;
}
}
}
题目描述:
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
思路分析:
使用回溯法:涉及多重循环就考虑使用回溯法,回溯法通过递归实习多重for循环
backTracking函数中n下标:涉及不同的集合,每个集合取一个元素,所以n不是各个集合中的下标,而是遍历题目传入的数字字符串的。
代码实现:
class Solution {
List<String> result=new ArrayList<>();
public List<String> letterCombinations(String digits) {
if(digits==null || digits.length()==0) return result;
String[] stringArr={"","","abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};//0.1没对应字母
backTracking(digits,stringArr,0);
return result;
}
StringBuilder temp=new StringBuilder();
private void backTracking(String digits,String[] stringArr,int n){//n已存字母数
if(n==digits.length()){
result.add(temp.toString());
return;
}
String str=stringArr[digits.charAt(n)-'0'];//这一位数字对应的字符串
for(int i=0;i<str.length();i++){
temp.append(str.charAt(i));
backTracking(digits,stringArr,n+1);
temp.deleteCharAt(temp.length()-1);
}
}
}