代码随想录刷题训练营DAY25|回溯part2

216.组合总和III

在这里插入图片描述
选取过程:
K相当于树的深度,9相当于树的宽度,和为4
在这里插入图片描述

class Solution {
    List<Integer> path=new ArrayList<>();
    List<List<Integer>> result=new ArrayList<>();
    
    public List<List<Integer>> combinationSum3(int k, int n) {
        backtracking(n, k, 0, 1);//第一个backtracking,sum=0,startIndex=1
        return result;

    }

     public void backtracking(int targetSum,int k,int sum,int startIndex){
        //终止条件
        if(path.size()==k){
            //如果path的大小和k一样,check sum是否和目标和一样
            if(sum==targetSum){
                result.add(new ArrayList<>(path));
            }
            return;
        }
        //横向遍历
        for(int i=startIndex;i<=9;i++){
            sum=sum+i;//更新和
            path.add(i);//更新路径
            backtracking(targetSum,k,sum,i+1);//纵向遍历
            sum=sum-i;//回溯
            //删除最后一个元素
            path.remove(path.size()-1);
        }
    }
}

单层遍历逻辑:
● 第一层递归:初始startIndex=1,选取1,path加入1,变为[1],sum为1.
○ 调用backtracking(…,2),即从2开始寻找剩下的数加入组合。
● 第二层递归:这里开始遍历i的值从2开始。
○ 当i=2,path加入2,变为[1, 2],sum=3。满足条件(path.size() == k),再判断和是否满足=4?并不满足,不加入到result里,但是终止。此时sum-2=1,path变回[1]
○ 当i=3,path加入3,变为[1, 3],此时sum满足条件=4,将[1, 3]添加到result中,然后移除3,sum-3再次回到1,path回到[1]。
○ 当i=4,path加入4,变为[1, 4],sum=5不满足和为4的条件,然后移除4,path回到[1],sum-4=1
○ …
● 回到第一层递归:完成所有i=1时的递归,移除1,path变回[]。
● i=2的递归开始:此时从2开始重复上述过程,直到遍历完所有可能的组合。

电话号码组合

思路:回溯法解决n个for循环的问题
字母与数字的映射,可以定义一个map
在这里插入图片描述
三部曲
● 确定回溯参数
○ 需要传入数字串,index记录遍历到第几个数字(题目中的数字字符串)
● 确定终止条件
○ index=digits.size(两个数字就是两个字母,三个数字就是三个字母)
● 单层逻辑
○ 根据数字取出对应的字符
○ for循环遍历字母
○ 取字母组合
○ 回溯

class Solution {
    List<String> result=new ArrayList<>();
    StringBuilder path = new StringBuilder();
    public List<String> letterCombinations(String digits) {
      //空串判断
        if("".equals(digits)){
            return result;
        }
        backtracking(digits,0);
        return result;
    }
    
       /**
     * 回溯
     * @param digits 数字字符串
     * @param index 当前的数字
     */
    public void backtracking(String digits,int index){
    if(index==digits.length()){
        result.add(path.toString());
        return;
    }
    String digit=String.valueOf(digits.charAt(index));
    String letters=findLetter(digit);//查询每个数字对应的字符集
    for(int i=0;i<letters.length();i++){
        path.append(letters.charAt(i));
        backtracking(digits, index+1);
        path.deleteCharAt(path.length()-1);
    }

}

    /**
     * 键盘字典
     * @param number 数字
     * @return 对应的字母
     */
    private String findLetter(String number){
    Map<String,String> tel=new HashMap<>();
    tel.put("2", "abc");
    tel.put("3", "def");
    tel.put("4", "ghi");
    tel.put("5", "jkl");
    tel.put("6", "mno");
    tel.put("7", "pqrs");
    tel.put("8", "tuv");
    tel.put("9", "wxyz");
    if(tel.containsKey(number)){
        return tel.get(number);
    }
    return "";
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值