代码随想录算法训练营第二十五天|LeetCode216,17
216.组合总和III
相比于上一道题,只是多了一个sum == n的条件,在不考虑剪枝的情况下,很容易写出
考虑剪枝的条件。
已选元素总和如果已经大于n(图中数值为4)了,那么往后遍历就没有意义了,直接剪掉。
List<List<Integer>> result;
List<Integer> path;
public void backtracking(int k, int n, int startIndex, int sum){
if (sum > n){
return;
}
if (path.size() == k && sum == n){
result.add(new ArrayList<>(path));
}else 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.remove(path.size()-1);
}
}
public List<List<Integer>> combinationSum3(int k, int n) {
result = new ArrayList<>();
path = new ArrayList<>();
backtracking(k,n,1,0);
return result;
}
17.电话号码的字母组合
要解决的问题:
数字和字母如何映射
通过新建一个String数组,即可实现数字与字母的映射,实际上就是运用了哈希表。
由于要使用多层for循环嵌套,因此考虑使用回溯算法,要传入的参数除了题目中给的digits,然后还要有一个参数就是int型的index,用来记录处理到第几个数字了。
String[] letterMap = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
List<String> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
//index用来判断当前处理到digits的第几个字母了
public void backuptracking(String digits, int index){
if (index == digits.length()){
result.add(new String(sb));
return;
}
//获取当前数字所代表的字母
String letters = letterMap[digits.charAt(index) - '0'];
for (int i = 0; i < letters.length();i++){
sb.append(letters.charAt(i));
backuptracking(digits,index+1);
sb.deleteCharAt(sb.length()-1);//回溯处理
}
}
public List<String> letterCombinations(String digits) {
if (digits == null || digits.length()==0){
return result;
}
backuptracking(digits,0);
return result;
}
此外,最好考虑输入1 * #按键等等异常情况