代码随想录训练营第二十二天| 77. 组合 216.组合总和III 17.电话号码的字母组合

发布于:2024-12-19 ⋅ 阅读:(10) ⋅ 点赞:(0)

 77. 组合

题目链接/文章讲解: 代码随想录

经典回溯 一点都看不懂 所以就看题解慢慢来吧

Java代码:

class Solution{
    //未剪支回溯
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> combine(int n, int k){
        backtracking(n, k ,1);
        return result;
    }

    public void backtracking(int n , int k, int startIndex){
        if(path.size() == k){
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i = startIndex; i <= n;i++){
            path.add(i);
            backtracking(n, k, i + 1);
            path.removeLast();//回溯
        }
    }
}
class Solution{
    List<List<Integer>> result = new ArrayList<>();
    LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> combine(int n, int k){
        combinehelper(n, k, 1);
        return result;
    }
    //每次从集合里选元素 可选择范围随着选择进行而收缩 调整可选择的范围
    //就是要考startindex用来记录本层递归的中 集合从哪里开始遍历
    private void combinehelper(int n, int k, int startindex){
        //终止条件
        if(path.size() == k){
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i = startindex; i <= n - (k - path.size()) + 1; i++){
            path.add(i);
            combinehelper(n, k, i + 1);
            path.removeLast();
        }
    }
}

 216.组合总和III 

题目链接/文章讲解: 代码随想录

Java代码:

 

class Solution {
    List<List<Integer>> result = new ArrayList<>();
    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));
        }

        //剪枝 9 - (k - path.size()) + 1
        //需要重点理解
        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.电话号码的字母组合 

 题目链接/文章讲解:代码随想录

这道题我自己有一些想法 但是实现不出来 最后还是看题解了 需要多练习 感觉回溯这里确实不懂 回来多理解理解

Java代码: 

class Solution{
    //设置全局列表存储最后结果
    List<String> list = new ArrayList<>();

    public List<String> letterCombinations(String digits){
        if(digits == null || digits.length() == 0){
            return list;
        }
        //初始对应所有的数字 为了直接对应2-9 新增两个无效的字符串
        String[] numstring = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        //迭代处理
        backtracking(digits, numstring, 0);
        return list;
    }

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

    //比如digits如果是“23”, num 为 0, 则 str 表示 2 对应的 abc
    public void backtracking(String digits, String[] numstring, int num){
        //遍历全部一次记录一次得到的字符串
        if(num == digits.length()){
            list.add(temp.toString());
            return;
        }
        //str 表示当前 num 对应的字符串
        String str = numstring[digits.charAt(num) - '0'];
        for(int i = 0; i < str.length(); i++){
            temp.append(str.charAt(i));
            //递归处理下一层
            backtracking(digits, numstring, num + 1);
            //剔除末尾的继续尝试
            temp.deleteCharAt(temp.length() - 1);
        }
    }
}

 

 


网站公告

今日签到

点亮在社区的每一天
去签到