代码随想录算法训练营day 25 |216.组合总和III、17.电话号码的字母组合

216.组合总和III

代码随想录

思路:

和组合的思路一样,加了总和剪枝的限制。

代码:

class Solution {
    List> res = new ArrayList<>();
    LinkedList paths = new LinkedList<>();
    public List> combinationSum3(int k, int n) {
        backtracking(k, n, 0, 1);
        return res;
    }
    private void backtracking(int k, int n, int sum, int startindex){
        //if(paths.size() > k) return;
        if(sum > n) return;//针对总和的剪枝
        if(paths.size() == k && sum == n){
            res.add(new ArrayList<>(paths));
            return;
        }

        for(int i = startindex; i <= 9 - (k - paths.size()) + 1; i++){//针对size的剪枝,也可此处不写,在终止条件写
            sum += i;
            paths.add(i);
            backtracking(k, n, sum, i + 1);
            sum -= i;
            paths.removeLast();
        }
    }
}

需要注意的点:

1、size的剪枝可以放在终止条件,也可放在循环处

2、有总和的限制,所以也需要剪枝。

17.电话号码的字母组合

代码随想录

思路:

每一层循环的变量是数字对应的字符串,

代码:

class Solution {
    List res = new ArrayList<>();
    StringBuilder paths = new StringBuilder();
    String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    public List letterCombinations(String digits) {
        if(digits == null || digits.length() == 0) return res;
        backtracking(digits, 0);
        return res;
    }

    private void backtracking(String digits, int num){
        if(digits.length() == num){
            res.add(paths.toString());
            return;
        }
        String str = numString[digits.charAt(num) - '0'];
        for(int i = 0; i < str.length(); i++){
            paths.append(str.charAt(i));
            backtracking(digits, num + 1);
            paths.deleteCharAt(paths.length() - 1);
        }
    }
}

需要注意的点:

1、使用StringBuilder进行结果字符串的拼接,效率高。

2、需要用一个变量控制读取每个数字对应的字符串,并且将其作为终止判断的标志。

你可能感兴趣的:(算法,java,数据结构)