刷题日记22 | 216.组合总和III、17.电话号码的字母组合

81 阅读1分钟

刷题日记22

今天是回溯算法的第二天,组合问题真的很经典,要把它理解成一棵N叉树,这棵树的宽度就是for循环,这树的深度就是递归(回溯)。

216. 组合总和 III

class Solution {
    public List<List<Integer>> res = new ArrayList<>();
    public LinkedList<Integer> path = new LinkedList<>();
    public List<List<Integer>> combinationSum3(int k, int n) {
        backTracking(k, n, 1);
        return res;
    }
    public void backTracking(int k, int n, int startIndex){
        if(path.size() == k){
            int sum = path.stream().mapToInt(Integer::intValue).sum();
            if(sum == n) res.add(new ArrayList(path));
            return;
        }
        for(int i = startIndex; i <= 9; i++){
            path.offerLast(i);
            backTracking(k, n, i+1);
            path.pollLast();
        }
    }
}

17. 电话号码的字母组合

一道细节上有点难度的题,要先把题目中输入的数字转换成字母,这就需要一个map来实现转换,实际上我们可以用更简单的string数组,然后再通过digits.charAt() - '0' 的方式实现char到int的转换。后面的内容就是基础的回溯算法了。

class Solution {
    public String[] map = {
            "",
            "",
            "abc",
            "def",
            "ghi",
            "jkl",
            "mno",
            "pqrs",
            "tuv",
            "wxyz"
        };
    public List<String> res = new ArrayList<>();
    public StringBuilder sb = new StringBuilder();
    public List<String> letterCombinations(String digits) {
        if(digits == null || digits.length() == 0) return res;
        backTracking(digits, 0);
        return res;
    }
    public void backTracking(String digits, int startIndex){
        if(startIndex == digits.length()){
            res.add(sb.toString());
            return;
        }
        String letter = map[digits.charAt(startIndex) - '0'];
        for(int i = 0; i < letter.length(); i++){
            sb.append(letter.charAt(i));
            backTracking(digits, startIndex+1);
            sb.deleteCharAt(sb.length() - 1);
        }
    }
}