目录
216.组合总和III
题解思路:
本题和77题思路类似,主要是熟悉回溯算法的模板写法,然后就是本题存在的两个剪枝情况,可以减少搜索的时间,具体的剪枝操作如下(代码中有详细注释):
剪纸操作一:如果添加的元素和大于目标之和时,及时return结束本次递归,进行下一次递归操作即可;
剪枝操作二,控制要达到k个个数时,最多还需要遍历到哪里结束即可,具体操作为9 - (k - path.size()) + 1!!!
class Solution {
LinkedList<Integer> path = new LinkedList<>();
List<List<Integer>> result = 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){
if(sum > n) return ; //剪纸操作一:如果添加的元素和大于目标之和时,及时return结束本次递归,进行下一次递归操作即可
if(path.size() == k ){
if(sum == n){
result.add(new LinkedList(path));
return;
}
}
for(int i = startIndex; i <= 9 - (k - path.size()) + 1; i++ ){ //9 - (k - path.size()) + 1:这里是剪枝操作二,控制要达到k个个数时,最多还需要遍历到哪里结束即可
path.add(i); //往path路径中及时添加元素
sum += i; //添加的元素及时相加操作
backtracking(k, n, i + 1); //不断的朝着深度方向进行搜索,直到遇到return结束方法的语句才算完成一次递归,紧接着进行回溯操作
path.removeLast(); //递归遇到return后及时减去刚添加的元素,回溯到第一次递归的状态
sum -= i; //递归遇到return后及时减去刚添加的元素,回溯到前一次递归的状态
}
}
}
17.电话号码的字母组合
本题大家刚开始做会有点难度,先自己思考20min,没思路就直接看题解。
题目链接/文章讲解:代码随想录
题解思路:
本题还是得有卡哥指路的,否则不会这么容易想到这么全面的解法,主要是先第一步:先把数字键盘通过数组下标映射成字符串,然后取字符串里面的字母组合,然后画出对应的树形结构进行一步一步分析,因为我第一次写这道题就是完全不知道从哪里下手,看到题目直接懵逼了,根据树形的求解思路再找出里面的关系就好。
class Solution {
String[] mapLetter = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"}; //第一步:先把数字键盘通过数组下标映射成字符串,然后取字符串里面的字母组合
LinkedList<String> path = new LinkedList<>();
List<String> result = new ArrayList<>();
StringBuilder temp = new StringBuilder(); //大量的字符串拼接可以选择更为高效的StringBuilder
public List<String> letterCombinations(String digits) {
if(digits == null || digits.length() == 0) return result; //这个剪枝操作是真恶心,还是需要直接判断如果digits == [""]或者不存在时时,直接return结果集即可
bancktracking(digits,0);
return result;
}
public void bancktracking(String digits, int index){ //index变量指向的是给定的数字字符串中的下标索引值,由于结果集中的大小和数字字符串大小一致,所以可以用过索引值控制回溯算法的终止条件,如下所示
if(index == digits.length()){ //index从0开始索引给定的数字字符,通过index的索引值控制递归的终止条件,只有当满足终止条件时,才进行结果的处理
result.add(temp.toString());
return;
}
String letter = mapLetter[digits.charAt(index) - '0']; //digits[index]:获取给定数字字符串指定索引值的数字字符,从0开始获取的;digits[index] - '0':获取对应数字字符的int的数,传入到映射数组中,再获取数字字符对应的字符串!!!
//这里要注意踩坑,一定是digits[index] - '0':表示两个字符串进行相加操作,得到的是int类型结果,'2'- '0' == 2,而不是digits[index] - 0:表示吧'2'先转换成ASCII码,其数值为50,再与0进行相减操作;
for(int i = 0; i < letter.length(); i++){
temp.append(letter.charAt(i));
bancktracking(digits, index + 1);
temp.deleteCharAt(temp.length() - 1);
}
}
}