[豪の算法奇妙冒险] 代码随想录算法训练营第二十二天 | 77-组合、216-组合总和Ⅱ、17-电话号码的字母组合

代码随想录算法训练营第二十二天 | 77-组合、216-组合总和Ⅱ、17-电话号码的字母组合


LeetCode77 组合

题目链接:https://leetcode.cn/problems/combinations/

文章讲解:https://programmercarl.com/0077.组合.html

视频讲解:https://www.bilibili.com/video/BV1ti4y1L7cv/?vd_source=b989f2b109eb3b17e8178154a7de7a51

​ start用来记录下一轮回溯遍历i的起始值,以防止收割结果时出现重复的组合

​ records这个数组的大小如果达到k,说明找到了一个子集大小为k的组合,收割结果并结束当前递归

​ 递归回来记得要进行回溯操作,撤销本次处理的结果

​ 回溯法的搜索过程就是一个树型结构的遍历过程,for循环用来横向遍历,递归的过程是纵向遍历

image-20251229142611737

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> records = new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        backTracking(n, k, 1);
        return result;
    }

    public void backTracking(int n, int k, int start){
        if(records.size() == k){
            result.add(new ArrayList<>(records));
            return;
        }
        for(int i = start; i <= n; i++){
            records.add(i);
            backTracking(n, k, i + 1);
            records.removeLast();
        }
    }
}

​ 加入剪枝操作,优化遍历过程

image-20251229150947749

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> records = new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        backTracking(n, k, 1);
        return result;
    }

    public void backTracking(int n, int k, int start){
        if(records.size() == k){
            result.add(new ArrayList<>(records));
            return;
        }
        for(int i = start; i <= n - (k - records.size()) + 1; i++){
            records.add(i);
            backTracking(n, k, i + 1);
            records.removeLast();
        }
    }
}

LeetCode216 组合总和Ⅱ

题目链接:https://leetcode.cn/problems/combination-sum-iii/description/

文章讲解:https://programmercarl.com/0216.组合总和III.html

视频讲解:https://www.bilibili.com/video/BV1wg411873x/?vd_source=b989f2b109eb3b17e8178154a7de7a51

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

image-20251229151811914

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    List<Integer> records = new ArrayList<>();
    int sum = 0;
    public List<List<Integer>> combinationSum3(int k, int n) {
        backTracking(k, n, 1);
        return result;
    }

    public void backTracking(int k, int n, int start){
        if(sum > n){
            return;
        }
        if(sum == n && records.size() == k){
            result.add(new ArrayList<>(records));
            return;
        }
        for(int i = start; i <= 9 - (k-records.size()) + 1; i++){
            records.add(i);
            sum += i;
            backTracking(k, n, i+1);
            sum -= i;
            records.removeLast();
        }
    }
}

LeetCode17 电话号码的字母组合

题目链接:https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/

文章讲解:https://programmercarl.com/0017.电话号码的字母组合.html

视频讲解:https://www.bilibili.com/video/BV1yV4y1V7Ug/?vd_source=b989f2b109eb3b17e8178154a7de7a51

​ 数字和字母通过一个String数组进行映射

​ 使用回溯法来解决n个for循环的问题,遍历的深度就是输入digits的长度,而叶子节点就是要收集的结果

​ 此时backTracking这个index是记录遍历第几个数字了,是用来遍历题目中给出的数字字符串digits的,同时index也表示树的深度,不同于之前组合那两题的startIndex

​ 终止条件就是 index == digits.size 时,收割结果并返回

​ 题目所给测试集没有异常数据,但面试时写代码一定要考虑到排除异常数据

image-20251229164132214

class Solution {
    String[] letterMap = {" ", " ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    StringBuilder records = new StringBuilder();
    List<String> result = new ArrayList<>();

    public List<String> letterCombinations(String digits) {
        backTracking(digits, 0);
        return result;
    }

    public void backTracking(String digits, int curDigitIndex){
        if(curDigitIndex == digits.length()){
            result.add(records.toString());
            return;
        }
        int curDigit = digits.charAt(curDigitIndex) - '0';
        String letter = letterMap[curDigit];

        for(int i = 0; i < letter.length(); i++){
            records.append(letter.charAt(i));
            backTracking(digits, curDigitIndex+1);
            records.deleteCharAt(records.length()-1);
        }
    }
}
posted @ 2025-12-29 16:49  SchwarzShu  阅读(4)  评论(0)    收藏  举报