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

LeetCode 216.组合总和III 

本题和LeetCode77有相似之处,只是回溯算法的递归终止条件需要判断当前k个数之和是否等于n。代码如下:

class Solution {
    LinkedList<Integer> path = new LinkedList<>();
    List<List<Integer>> result = new ArrayList<>();
    int sum = 0;
    public List<List<Integer>> combinationSum3(int k, int n) {
        backtracking(n,k,1);
        return result;
    }
    public void backtracking(int n, int k, int start) {
        // 剪枝
        if(sum > n) return;
        
        if(path.size() == k) {
            if(sum == n) {
                result.add(new ArrayList(path));
            }
            return;
        }
        for(int i=start; i<=9 - (k - path.size()) + 1; i++) {
            path.add(i);
            sum += i;
            backtracking(n, k, i+1);
            sum -= path.getLast();
            path.removeLast();
        }
    }
}

剪枝操作:

1.当sum大于n时,已经不需要再遍历了:if(sum > n) return;

2.同LeetCode77,可以对for循环进行剪枝,i<=9应写为9-(k-path.size())+1,因为再往后,凑不齐k个数了,就无需遍历。

LeetCode 17.电话号码的字母组合 

本题需要解决以下3个问题:

1.数字和字母如何映射;

2.如何根据数字字符串的长度实现嵌套循环;

3.处理输入0 1 * #等特殊按键情况(本题并不要求处理,但在面试中可能要求处理)。

思路:用二维字符串数组根据数字的值作为下标来取对应的字母字符串,使用回溯法来灵活处理根据数字字符串长度个for循环的问题。

需要注意处理输入为空的边界情况,不然会出现空指针的错误。StringBuilder转String用toString方法就可以,撤销回溯操作时也要注意字符串下标不要越界。本题直接套用回溯法的模版还算比较简单,但要注意细节的处理,二刷时希望还能理解并通过。代码如下:

class Solution {
    List<String> result = new ArrayList<>();
    StringBuilder s = new StringBuilder();
    String[] letterMap = {
            "", // 0
            "", // 1
            "abc", // 2
            "def", // 3
            "ghi", // 4
            "jkl", // 5
            "mno", // 6
            "pqrs", // 7
            "tuv", // 8
            "wxyz", // 9
    };
    public List<String> letterCombinations(String digits) {
        if(digits == null || digits.length() == 0) return result;
        backtracking(digits, 0);
        return result;
    }
    public void backtracking(String digits, int index){
        if(index == digits.length()){
            result.add(s.toString());
            return;
        }
        int digit = digits.charAt(index) - '0';
        String letters = letterMap[digit];
        for(int i=0; i<letters.length(); i++){
            s.append(letters.charAt(i));
            backtracking(digits, index+1);
            s.deleteCharAt(s.length() - 1);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值