代码随想录Day25 | 77. 组合总和III、17. 电话号码的字母组合 | 回溯

82 阅读1分钟

216. 组合总和 III

题目链接:216. 组合总和 III

思路: 整体思路跟昨天那道差不多,注意减枝操作。

class Solution {

    LinkedList<Integer> track = new LinkedList<>();
    List<List<Integer>> res = new LinkedList<>();
    int presum;

    public List<List<Integer>> combinationSum3(int k, int n) {
        backtrack(k, n, 1);
        return res;
    }

    void backtrack(int k, int n, int start) {
        if (presum > n) {
            return;
        }
        if (track.size() == k) {
            if (presum == n) {
                res.add(new LinkedList<>(track));
            }
            return;
        }
        for (int i = start; i <= 9 - (k - track.size()) + 1; i++) {
            track.add(i);
            presum += i;
            backtrack(k, n, i + 1);
            track.removeLast();
            presum -= i;
        }
    }
}

17. 电话号码的字母组合

题目链接:17. 电话号码的字母组合

思路: 跟之前不同的是,之前是求数字的组合,现在每个数字又是一个集合,所以要在for循环里再套一个for循环。

class Solution {

    String[] str = new String[] {"","","abc","def","ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    List<String> res = new LinkedList<>();

    public List<String> letterCombinations(String digits) {
        if (digits.isEmpty()) {
            return res;
        }
        backtrack(digits, 0, new StringBuilder());
        return res;
    }

    void backtrack(String digits, int start, StringBuilder sb) {
        if (sb.length() == digits.length()) {
            res.add(sb.toString());
            return;
        }
        for (int i = start; i < digits.length(); i++) {
            int digit = digits.charAt(i) - '0';
            for (char c : str[digit].toCharArray()) {
                sb.append(c);
                backtrack(digits, i + 1, sb);
                sb.deleteCharAt(sb.length() - 1);
            }
        }
    }
}