216.组合总和III
题目链接/文章讲解:代码随想录
视频讲解:和组合问题有啥区别?回溯算法如何剪枝?| LeetCode:216.组合总和III_哔哩哔哩_bilibili
//k相当于了树的深度,9(因为整个集合就是9个数)就是树的宽度, n是k个数的和
class Solution {
//新建List保存result
List<List<Integer>> result = new ArrayList<>();
//新建List保存每次得到的路径path
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
backtracking(k, n, 1, 0);
return result;
}
//定义回溯方法
private void backtracking(int k, int n, int startIndex, int sum) {
//剪枝
if(sum > n) {
return;
}
if(path.size() > k) {
return;
}
//终止条件
if(path.size() == k) {
if(sum == n) {
result.add(new LinkedList(path));
}
return;
}
//for循环,单层搜索过程
// 剪枝 i <= 9 - (k - path.size()) + 1; 如果还是不清楚
// 也可以改为 if (path.size() > k) return 放在终止条件; 执行效率上是一样的
for(int i = startIndex; i <= 9; i++) {
sum += i;
path.add(i);
backtracking(k, n, i + 1, sum);
//回溯
sum -= i;
//回溯
path.removeLast();
}
}
}
17.电话号码的字母组合
题目链接/文章讲解:代码随想录
视频讲解:还得用回溯算法!| LeetCode:17.电话号码的字母组合_哔哩哔哩_bilibili
//Java 字符串是不可变的,但是还是可以通过新建字符串的方式来进行字符串的拼接。
//StringBuilder是设计来定义可变字符串和字符串的变化操作的,效率最高
//多个集合求组合; 注意index的含义与一个集合的startIndex不同
class Solution {
//初始字母对应的数字; 用字符串数组存储
String letterMap[] = {
" ", //0
"", //1
"abc", //2
"def", //3
"ghi", //4
"jkl", //5
"mno", //6
"pqrs", //7
"tuv", //8
"wxyz" //9
};
//新建List保存result
ArrayList<String> result = new ArrayList();
//新建StringBuilder保存每次得到的路径path
StringBuilder path = new StringBuilder();
public List<String> letterCombinations(String digits) {
if(digits == null || digits.length() == 0){
return result;
}
backtracking(digits, 0);
return result;
}
//定义回溯方法
//这个index是记录遍历第几个数字了,就是用来遍历digits的(题目中给出数字字符串)
public void backtracking(String digits, int index){
//base case终止条件
if(index == digits.length()){
//注意path.toString()再加入结果集
result.add(path.toString());
return;
}
//从之前定义的letterMap根据数字找到对应字母
//这里给定的digits是String,需要将index指向的数字转为int
int digit = digits.charAt(index) - '0';
//取数字对应的字符集(String数组的方法)
String letters = letterMap[digit];
//for循环,单层搜索过程
for(int i = 0; i < letters.length(); i++){
//处理节点加入path;注意加入String的方法
path.append(letters.charAt(i));
//递归
backtracking(digits, index+1);
//回溯;注意删除最后一个字符的方法
path.deleteCharAt(path.length() - 1);
}
}
}