代码随想录算法训练营第25天|216. 组合总和III、17. 电话号码的字母组合

216. 组合总和III

k相当于了树的深度,9(因为整个集合就是9个数)就是树的宽度。

  • 确定递归函数参数
    依然需要一维数组path来存放符合条件的结果,二维数组result来存放结果集。sum为已经收集的元素的总和,也就是path里元素的总和;startIndex(int)为下一层for循环搜索的起始位置。
  • 确定终止条件
    如果path.size() 和 k相等了,就终止。如果此时path里收集到的元素和(sum) 和targetSum(就是题目描述的n)相同了,就用result收集当前的结果。
  • 单层搜索过程
    处理过程就是 path收集每次选取的元素,相当于树型结构里的边,sum来统计path里元素的总和。
  • 剪枝
    和其他组合问题一样,for循环的范围可以剪枝。
    代码随想录算法训练营第25天|216. 组合总和III、17. 电话号码的字母组合_第1张图片
class Solution {
    private List<List<Integer>> result = new ArrayList<>();
    private LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        backTracking(n, k, 1, 0);
        return result;
    }

    private void backTracking(int targetSum, int k, int startIndex, int sum){
        //剪枝
        if(sum > targetSum) return;

        if(path.size() == k){
            if(sum == targetSum){
                result.add(new ArrayList<>(path));
            }
            return;
        }

        for(int i = startIndex; i <= 9 - (k - path.size()) + 1; i++){
            path.add(i);
            sum += i;
            backTracking(targetSum, k, i + 1, sum);
            //回溯
            path.removeLast();
            sum -= i;
        }
    }
}

17. 电话号码的字母组合

  • 数字和字母的映射问题
    定义一个数组numString,并且在前面加上两个空字符,使2-9与数组中的顺序对应上。
  • 回溯法来解决n个for循环的问题
    设置一个参数index,记录当前遍历到第几个数字了。同时index也表示树的深度。终止条件就是如果index 等于 输入的数字个数(digits.size)。
    代码随想录算法训练营第25天|216. 组合总和III、17. 电话号码的字母组合_第2张图片
class Solution {
    List<String> list = new ArrayList<>();
    public List<String> letterCombinations(String digits) {
        if(digits == null || digits.length() == 0){
            return list;
        }
        //初始对应所有数字
        String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        backTracking(digits, numString, 0);
        return list;
    }

    //每次迭代获取一个字符串,所以会设计大量的字符串拼接,所以这里选择更为高效的 StringBuild
    StringBuilder temp = new StringBuilder();

    private void backTracking(String digits, String[] numString, int index){
        if(index == digits.length()){
            list.add(temp.toString());
            return;
        }
        String str = numString[digits.charAt(index) - '0'];
        for(int i = 0; i < str.length(); i++){
            temp.append(str.charAt(i));
            backTracking(digits, numString, index + 1);
            temp.deleteCharAt(temp.length() - 1);
        }
    }
}

今日总结

今天的题比较简单,但是因为一些sb事,完全没有心思自己先思考一遍,都是直接看题解了。但是回溯总结一句话吧,画树,确定集合!加油!

你可能感兴趣的:(算法,数据结构,leetcode)