一、216.组合总和Ⅲ
这道题与组合问题基本类似,就是最后在收集结果的时候需要判断一下是否等于给定的值。同时,还多了一个剪枝操作,如果当前的和已经大于给定的值,则直接return,不再往下遍历。
以下是代码部分:
public class 组合总和Ⅲ216 {
List<List<Integer>> result = new ArrayList<>();
List<Integer> path = new ArrayList<>();
public List<List<Integer>> combinationSum3(int k, int n) {
backtracking(k, n, 1);
return result;
}
private void backtracking(int k, int n, int start){
if(k == 0){
if(n == 0)
result.add(new ArrayList<>(path));
return;
}
//剪纸操作
if(n<0)
return;
//剪枝:这里记得+1
for(int i = start; i < 10-k+1;i++){
path.add(i);
backtracking(k-1, n-i, i+1);
path.remove(path.size()-1);
}
}
}
二、17.电话号码的字母组合
这道题我使用的方法是直接通过if else把所有情况都写一遍。但其实这样代码看着很长,有些违背回溯算法的初衷了。
以下是我的代码:
public class 电话号码的字母组合17 {
List<String> result = new ArrayList<>();
StringBuilder path = new StringBuilder();
public List<String> letterCombinations(String digits) {
//踩坑:没有判断空字符串的情况
if(digits.equals(""))
return result;
backtracking(0, digits);
return result;
}
private void backtracking(int k, String digits){
if( k == digits.length()){
result.add(new String(path));
return;
}
//踩坑:判断的时候没有= 即i<'c'
if(digits.charAt(k) == '2'){
for(char i = 'a';i<='c';i++){
path.append(i);
backtracking(k+1, digits);
path.deleteCharAt(path.length()-1);
}
}else if(digits.charAt(k) == '3'){
for(char i = 'd';i<='f';i++){
path.append(i);
backtracking(k+1, digits);
path.deleteCharAt(path.length()-1);
}
}else if(digits.charAt(k) == '4'){
for(char i = 'g';i<='i';i++){
path.append(i);
backtracking(k+1, digits);
path.deleteCharAt(path.length()-1);
}
}else if(digits.charAt(k) == '5'){
for(char i = 'j';i<='l';i++){
path.append(i);
backtracking(k+1, digits);
path.deleteCharAt(path.length()-1);
}
}else if(digits.charAt(k) == '6'){
for(char i = 'm';i<='o';i++){
path.append(i);
backtracking(k+1, digits);
path.deleteCharAt(path.length()-1);
}
}else if(digits.charAt(k) == '7'){
for(char i = 'p';i<='s';i++){
path.append(i);
backtracking(k+1, digits);
path.deleteCharAt(path.length()-1);
}
}else if(digits.charAt(k) == '8'){
for(char i = 't';i<='v';i++){
path.append(i);
backtracking(k+1, digits);
path.deleteCharAt(path.length()-1);
}
}else if(digits.charAt(k) == '9'){
for(char i = 'w';i<='z';i++){
path.append(i);
backtracking(k+1, digits);
path.deleteCharAt(path.length()-1);
}
}
}
}
看了题解后,发现竟然可以通过字符串数组的方式。
同时,也了解到怎样将一个字符转换为整型。通过 - ’ 0 ’ ,这里不要误以为0 == 0,实际上是0 == 48
以下是代码部分:
public class 电话号码的字母组合17 {
List<String> result = new ArrayList<>();
StringBuilder path = new StringBuilder();
public List<String> letterCombinations2(String digits) {
if(digits.length()==0)
return result;
String[] s =new String[]{"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
backtracking2(digits, s, 0);
return result;
}
private void backtracking2(String digits, String[] s, int k){
if( k == digits.length()){
result.add(new String(path));
return;
}
/*
字符转数组:
-'0' : 不要误以为0 == 0。 实际上是0 == 48。
*/
int index = digits.charAt(k) - '0';
String ss = s[index];
for (int i = 0; i < ss.length(); i++) {
path.append(ss.charAt(i));
backtracking2(digits, s, k+1);
path.deleteCharAt(path.length()-1);
}
}
}