216.组合总和III
思路:将问题抽象成树形结构,然后通过回溯法搜索答案。
class Solution {
private List<List<Integer>> res = new ArrayList<>();
private List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
backtracking(k, n, 1, 0);
return res;
}
public void backtracking(int k, int n, int start, int count) {
if (path.size() == k && count == n) {
List<Integer> temp = new ArrayList<>(path);
res.add(temp);
return;
}
int max = n > 9?9:n;
for (int i = start; i <= max; i++) {
path.add(i);
count += i;
backtracking(k, n, i + 1, count);
count -= i;
path.remove(path.size() - 1);
}
return;
}
}
做剪枝优化后代码
class Solution {
private List<List<Integer>> res = new ArrayList<>();
private List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
backtracking(k, n, 1, 0);
return res;
}
public void backtracking(int k, int n, int start, int count) {
if (count > n) { // 剪枝
return;
}
if (path.size() == k && count == n) {
List<Integer> temp = new ArrayList<>(path);
res.add(temp);
return;
}
for (int i = start; i <= 9 - (k - path.size()) + 1; i++) { // 剪枝
path.add(i);
count += i;
backtracking(k, n, i + 1, count);
count -= i;
path.remove(path.size() - 1);
}
return;
}
}
17.电话号码的字母组合
思路:将问题抽象为树形结构,然后用回溯法搜索全部结果。
class Solution {
private List<String> res = new ArrayList<>();
private StringBuilder path = new StringBuilder();
public List<String> letterCombinations(String digits) {
if ("".equals(digits)) return res;
String[] strs = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
backtracking(digits.toCharArray(), strs, 0);
return res;
}
public void backtracking(char[] ch,String[] strs, int start) {
if (path.length() == ch.length) {
String temp = new String(path);
res.add(temp);
return;
}
String word = strs[ch[start] - '0'];
for (int i = 0; i < word.length(); i++) {
path.append(word.charAt(i));
backtracking(ch, strs, start + 1);
path.deleteCharAt(path.length() - 1);
}
return;
}
}