代码训练营day25——求和组合与不同集合的回溯

求和组合与电话号码的字母组合

做算法题,画图很关键,特别是递归回溯这类题,“三步走”中第三步递归是如何进行的是很关键的,其他两步好解决,pram也可根据第三步来确定

一、求和组合

  • 注意path得用LinkedList, List类没有removeLast方法,直接用有些麻烦
  • 回溯操作是组合问题很关键的一步,可以减少时间复杂度,否者真和暴力求解无异了
  • 这里有两个剪枝操作
    class Solution {
        List<List<Integer>> result ;
        LinkedList<Integer> path;       // todo path得用LinkedList,要不然灭有封装removeLast方法
        public List<List<Integer>> combinationSum3(int k, int n) {
            result = new ArrayList<>();
            path = new LinkedList<>();
            travelbacking( n,k,0,1);
            return result;
        }

        // 返回值用void, 不需要统计调用次数
        public void travelbacking(int target,int k,int sum,int startIndex ){

            // 剪枝
            if (sum > target) {
                return;
            }

            if(target == sum && path.size() == k){
                result.add(new ArrayList<>(path));
                // sum = 0;      // 这里sum不用归零
                return ;
            }

            for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) { // 注意这里没有直接修改startIndex
                path.add(i);
                sum += i;
                travelbacking(target,k,sum,i+1);      // startindex要写这!
                path.removeLast();
                sum-= i;          // 一定要进行回溯
            }
        }
    }

电话号码的字母组合

  • 不同集合的字母组合
  • 字符串的处理也是值得关注的点
class Solution {
    LinkedList<String> path;
    List<String> result; // 新增一个变量来存储最终结果

    public List<String> letterCombinations(String digits) {
        path = new LinkedList<>();
        result = new LinkedList<>(); // 初始化结果列表

        if (digits == null || digits.length() == 0) {
            return result;
        }
        
        // 初始对应所有的数字
        String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        travelbacking(digits, numString, 0);
        return result;
    }

    public void travelbacking(String digits, String[] numString, int digitIndex) {
        // 当路径长度等于输入数字长度时,说明已经完成了一种组合
        if (digitIndex == digits.length()) {
            result.add(String.join("", path)); // 将当前路径转换为字符串并加入结果列表
            return;
        }

        String str = numString[digits.charAt(digitIndex) - '0']; // 获取当前数字对应的字母字符串
        for (char c : str.toCharArray()) { // 遍历该数字对应的每个字母
            path.add(Character.toString(c)); // 添加字母到路径中
            travelbacking(digits, numString, digitIndex + 1); // 递归处理下一个数字
            path.removeLast(); // 回溯,移除最后一个字母准备尝试下一个
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值