代码随想录算法训练营day25 | 216.组合总和III,17.电话号码的字母组合
216.组合总和III
解法一:回溯+剪枝
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
int sum = 0;
public List<List<Integer>> combinationSum3(int k, int n) {
backtracking(k,n,1);
return result;
}
public void backtracking(int k, int n,int startindex){
//终止条件,k控制递归深度
if(sum>n)return;//剪枝1
if(k==path.size()){
if(sum==n){
result.add(new ArrayList<>(path));
}
return;
}
//单层搜索
for(int i=startindex;i<=9-(k-path.size())+1;i++){//剪枝2
path.add(i);
sum+=i;
backtracking(k,n,i+1);
path.remove(path.size()-1);
sum-=i;
}
}
}
17.电话号码的字母组合
教程视频:https://www.bilibili.com/video/BV1yV4y1V7Ug
解法一:
class Solution {
List<String> result = new ArrayList<>();
List<Character> path = new ArrayList<>();
//初始对应所有的数字,为了直接对应2-9,新增了两个无效的字符串""
String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
public List<String> letterCombinations(String digits) {
//边界处理
if (digits == null || digits.length() == 0) {
return result;
}
backtracking(digits,0);
return result;
}
//参数index表示当前递归到字符串的索引
public void backtracking(String digits, int index){
if(path.size()==digits.length()){//digits长度控制递归深度
String s = "";
for(int i=0;i<path.size();i++){
s+=path.get(i);
}
result.add(s);
return;
}
//单层递归逻辑
int num = digits.charAt(index)-'0';//取出当前数字
String letters = numString[num];//取出当前数字对应字符串
for(int i=0;i<letters.length();i++){
path.add(letters.charAt(i));
backtracking(digits,index+1);
path.remove(path.size()-1);
}
}
}
总结
216.组合总和III:和组合类似的,只是添加了一个sum参数,看目前的累积和是多少,一样经典的递归三部曲
17.电话号码的字母组合:这题其实就是每个数字对应的字母集合不同了,和之前回溯题目的差别就在于其for循环可供的选择不同了,看清楚这点就和其他的类似