216.组合总和III
该题与 77.组合 大差不差,差别在与结束路径结束条件不一
完整代码如下:(直接借用了 77.组合 的剪枝)
class Solution {
List<List<Integer>> res = new LinkedList<>();
List<Integer> track = new LinkedList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
backtrack(k, n, 1, track);
return res;
}
int sum = 0;
public void backtrack(int k, int n, int startIndex, List<Integer> track){
if(sum > n){
return;
}
if(track.size() == k && sum == n){
res.add(new LinkedList<>(track));
return;
}
for(int i = startIndex; i <= 9 - (k - track.size()) + 1; i++){
sum += i;
track.add(i);
backtrack(k, n, i + 1,track);
sum -= i;
track.remove(track.size() - 1);
}
}
}
17.电话号码的字母组合
该题本质上还是组合问题。
主要问题是:每个数字代表一个不同的集合,需要在不同集合之间进行组合
借用卡哥的决策树:
该题需要解决的一个问题:数字与字母的映射关系
String[] mapping =new String[]{
"", // 0
"", // 1
"abc", // 2
"def", // 3
"ghi", // 4
"jkl", // 5
"mno", // 6
"pqrs", // 7
"tuv", // 8
"wxyz", // 9
};
接下来便是套用回溯模板,完整代码如下:
class Solution {
// 创建每个数字到字母的映射
String[] mapping =new String[]{
"",
"",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz",
};
List<String> res = new LinkedList<>();
StringBuilder sb = new StringBuilder();
public List<String> letterCombinations(String digits) {
if(digits.length() == 0){
return res;
}
backtrack(digits, 0, sb);
return res;
}
public void backtrack(String digits, int startIndex, StringBuilder sb){
// 满足一条完整路径
if(sb.length() == digits.length()){
res.add(sb.toString());
return;
}
// 先在数字集合 [digits] 中进行一次选择
for(int i = startIndex; i < digits.length(); i++){
// 将 i 指向的数字转化为 int
int digit = digits.charAt(i) - '0';
// 进行第二次选择,取数字对应的字符集合
for(char c : mapping[digit].toCharArray()){
sb.append(c);
backtrack(digits, i + 1, sb);
sb.deleteCharAt(sb.length() - 1);
}
}
}
}