【代码随想录刷题笔记】DAY25 第七章 回溯算法

216.组合总和III 

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

视频讲解:和组合问题有啥区别?回溯算法如何剪枝?| LeetCode:216.组合总和III_哔哩哔哩_bilibili

//k相当于了树的深度,9(因为整个集合就是9个数)就是树的宽度, n是k个数的和
class Solution {
    //新建List保存result
    List<List<Integer>> result = new ArrayList<>();
    //新建List保存每次得到的路径path
    LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        backtracking(k, n, 1, 0);
        return result;    
    }
    
     //定义回溯方法
    private void backtracking(int k, int n, int startIndex, int sum) {
        //剪枝
        if(sum > n) {
            return;
        }
        if(path.size() > k) {
            return;
        }
        //终止条件
        if(path.size() == k) {
            if(sum == n) {
                result.add(new LinkedList(path));
            }
            return;
        }
        //for循环,单层搜索过程
        // 剪枝 i <= 9 - (k - path.size()) + 1; 如果还是不清楚
        // 也可以改为 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.removeLast(); 
        }       
    }
}

17.电话号码的字母组合 

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

视频讲解:还得用回溯算法!| LeetCode:17.电话号码的字母组合_哔哩哔哩_bilibili

//Java 字符串是不可变的,但是还是可以通过新建字符串的方式来进行字符串的拼接。
//StringBuilder是设计来定义可变字符串和字符串的变化操作的,效率最高
//多个集合求组合; 注意index的含义与一个集合的startIndex不同
class Solution {
    //初始字母对应的数字; 用字符串数组存储
    String letterMap[] = {
            " ",    //0
            "",     //1
            "abc",  //2
            "def",  //3
            "ghi",  //4
            "jkl",  //5
            "mno",  //6
            "pqrs", //7
            "tuv",  //8
            "wxyz"  //9
    };
    //新建List保存result
    ArrayList<String> result = new ArrayList();
    //新建StringBuilder保存每次得到的路径path
    StringBuilder path = new StringBuilder();
    public List<String> letterCombinations(String digits) {
        if(digits == null || digits.length() == 0){
            return result;   
        }    
        backtracking(digits, 0);       
        return result;
    }
    
    //定义回溯方法
    //这个index是记录遍历第几个数字了,就是用来遍历digits的(题目中给出数字字符串)
    public void backtracking(String digits, int index){
        //base case终止条件
        if(index == digits.length()){
            //注意path.toString()再加入结果集
            result.add(path.toString());
            return;
        }
        //从之前定义的letterMap根据数字找到对应字母
        //这里给定的digits是String,需要将index指向的数字转为int
        int digit = digits.charAt(index) - '0';        
        //取数字对应的字符集(String数组的方法)
        String letters = letterMap[digit]; 
        //for循环,单层搜索过程
        for(int i = 0; i < letters.length(); i++){
            //处理节点加入path;注意加入String的方法
            path.append(letters.charAt(i));
            //递归
            backtracking(digits, index+1);
            //回溯;注意删除最后一个字符的方法
            path.deleteCharAt(path.length() - 1);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值