题目链接:216. 组合总和 III - 力扣(LeetCode)
作者思考:
本题和LeetCode77.组合很相似,本题只不过多加一步累加的操作。
我们需要明确树的深度是递归的过程,宽度是单层递归逻辑(for循环)
我们知道,有递归就有回溯,回溯是递归的附加物;在递归的代码中不一定看见回溯的身影,但是一定有回溯的思想出现。
开始递归前,首先想一下递归三部曲。
确定返回值和参数:
我们依旧吧result 和 path 定义成全局变量,当然 我们也可以将累加和sum 也定义为全局变量,不过创建一个新的对象的过程,会加大内存运行时间,不过也没有什么关系。
List<List<Integer>> result = new ArrayList<>();//存放结果集
List<Integer> path = new ArrayList<>();//结果集中的单个集合
在递归方法中 我们 定义四个参数
k:有多少个数字需要我们进行相加
n:数字和
sum:k结合中数字累加和
startindex:单层递归时元素的位置
public void backtracking(int k, int n,int sum, int startindex) {
}
确定终止条件:
当path的长度等于k 并却 path中元素的和等于目标n时 退出当前递归
if (path.size() == k && sum == n) {
result.add(new ArrayList<>(path));
return ;
}
单层递归逻辑:
for (int i = startindex; i <= 9; i++) {
sum += i;
path.add(i);
backtracking(k, n, sum, i+1);
sum -= i;//回溯
path.remove(path.size() -1);//回溯
}
完整代码
class Solution {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
backtracking(k, n, 0, 1);
return result;
}
public void backtracking(int k, int n,int sum, int startindex) {
if (path.size() == k && sum == n) {
result.add(new ArrayList<>(path));
return ;
}
for (int i = startindex; i <= 9; i++) {
sum += i;
path.add(i);
backtracking(k, n, sum, i+1);
sum -= i;
path.remove(path.size() -1);
}
return ;
}
}
题目链接: 17. 电话号码的字母组合 - 力扣(LeetCode)
作者思考:
在本题中,我认为最大的难点就是如何找到字母和数字合适的映射关系。
递归三部曲
确定返回值和参数:
本题还是将result结果集定义为全局变量
本题中索引传进来的参数为index,那为什么不和之前一样传入一个startindex,来记录下一次递归的位置呢?本题和之前组合 和 组合III不同的是 本题操作数组并不是在同一个数组中,并不需要去重,记录我们下一次的位置。
String[] words 就是我们穿入进来的字母
public void backtracking(String digits, String[] words, int index) {
}
确定终止条件:
index从0开始 指向digits字符串最后一位的下一位 也就是 index = digits.length()
if (index == digits.length()) {
result.add(sb.toString());
return ;
}
确定单层递归逻辑:
digits.charAt(index):取目标字符串中的单个字符
digits.charAt(index) - '0':将上述单个字符转为数字
words[digits.charAt(index) - '0']:取二位数组中的行
String str = words[digits.charAt(index) - '0'];//数字与字母的映射关系
for (int i = 0; i < str.length(); i++) {
sb.append(str.charAt(i));
backtracking(digits, words, index +1);
sb.deleteCharAt(sb.length() -1);//回溯
}
完整代码
class Solution {
List<String> result = new ArrayList<>();
public List<String> letterCombinations(String digits) {
if (digits == null || digits.length() == 0) {
return result;
}
String[] words = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
backtracking(digits, words, 0);
return result;
}
StringBuilder sb = new StringBuilder();
public void backtracking(String digits, String[] words, int index) {
//index从0开始 指向digits字符串最后一位的下一位 也就是 index = digits.length()
if (index == digits.length()) {
result.add(sb.toString());
return ;
}
String str = words[digits.charAt(index) - '0'];//数字与字母的映射关系
for (int i = 0; i < str.length(); i++) {
sb.append(str.charAt(i));
backtracking(digits, words, index +1);
sb.deleteCharAt(sb.length() -1);//回溯
}
return ;
}
}