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

76 阅读1分钟

216.组合总和III

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

思路:将问题抽象成树形结构,然后通过回溯法搜索答案。

20201123195717975.png

class Solution {
    private List<List<Integer>> res = new ArrayList<>();
    private List<Integer> path = new ArrayList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        backtracking(k, n, 1, 0);
        return res;
    }
    public void backtracking(int k, int n, int start, int count) {
        if (path.size() == k && count == n) {
            List<Integer> temp = new ArrayList<>(path);
            res.add(temp);
            return;
        }
        int max = n > 9?9:n;
        for (int i = start; i <= max; i++) {
            path.add(i);
            count += i;
            backtracking(k, n, i + 1, count);
            count -= i;
            path.remove(path.size() - 1);
        }
        return;
    }
}

做剪枝优化后代码

class Solution {
    private List<List<Integer>> res = new ArrayList<>();
    private List<Integer> path = new ArrayList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        backtracking(k, n, 1, 0);
        return res;
    }
    public void backtracking(int k, int n, int start, int count) {
        if (count > n) { // 剪枝
            return;
        }
        if (path.size() == k && count == n) {
            List<Integer> temp = new ArrayList<>(path);
            res.add(temp);
            return;
        }
        for (int i = start; i <= 9 - (k - path.size()) + 1; i++) { // 剪枝
            path.add(i);
            count += i;
            backtracking(k, n, i + 1, count);
            count -= i;
            path.remove(path.size() - 1);
        }
        return;
    }
}

17.电话号码的字母组合

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

思路:将问题抽象为树形结构,然后用回溯法搜索全部结果。

20201123200304469.png

class Solution {
    private List<String> res = new ArrayList<>();
    private StringBuilder path = new StringBuilder();
    public List<String> letterCombinations(String digits) {
        if ("".equals(digits)) return res;
        String[] strs = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        backtracking(digits.toCharArray(), strs, 0);
        return res;
    }
    public void backtracking(char[] ch,String[] strs, int start) {
        if (path.length() == ch.length) {
            String temp = new String(path);
            res.add(temp);
            return;
        }
        String word = strs[ch[start] - '0'];
        for (int i = 0; i < word.length(); i++) {
            path.append(word.charAt(i));
            backtracking(ch, strs, start + 1);
            path.deleteCharAt(path.length() - 1);
        }
        return;
    }
}