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

138 阅读2分钟

216.组合总和III

找出所有相加之和为 n 的 k 个数的组合,且满足下列条件:

  • 只使用数字1到9
  • 每个数字 最多使用一次 
    返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。

216. 组合总和 III - 力扣(Leetcode)

思路

根据题目意思,依次从 1 到 9 中取数,直到取到 k 个数,如果这 k 个数的和为 n,则找到一个组合,否则,这个组合不是我们的目标。依据该描述,我们使用回溯算法,对每种可能的组合进行遍历。
在每次回溯中,

  • [start, 9]中取一个数i后,下一个数在[i + 1, 9]中取得。
  • 如果当前组合path的元素数量为目标n了,判断当前所有元素的和total是否等于n,如果等于,则将这个组合加入到结果集中。
  • 如果当前组合中所有元素的和total大于n,则不用再取值了,当前组合不可能成为目标结果。

代码

class Solution {
    public List<List<Integer>> combinationSum3(int k, int n) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        backTracking(1, n, k, res, path, 0);
        return res;
    }

    private void backTracking(int start, int n, int k, List<List<Integer>> res, List<Integer> path, int total){

        if(path.size() == k){
            if(total == n){
                res.add(new ArrayList<>(path));
            }
            return;
        }

        if(total > n){
            return;
        }

        for(int i = start; i <= 9; i++){
            path.add(i);
            backTracking(i + 1,n,k,res,path,total + i);
            path.remove(path.size() - 1);
        }

    }
}

17.电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

  • 0 <= digits.length <= 4
  • digits[i] 是范围 ['2', '9'] 的一个数字。

17. 电话号码的字母组合 - 力扣(Leetcode)

思路

  1. 为了方便将数字匹配成相应的字母,将其所能对应的字符组成一个字符串,保存在字符串型的数组中。
  2. 为了让各数字直接对应字符串在数组中的下标,将数组下标为 01 的字符串设置为空字符串。
  3. 按照 digits 的顺序依次找到匹配的字符串,取字符串中每一个字符都算一种组合方式。回溯树的深度为digits的长度,第 index 层的宽度为 digits[index] 对应的字符串的长度。

代码

class Solution {
    public List<String> letterCombinations(String digits) {

        if(digits.length() == 0){
            return new ArrayList<String>();
        }

        String[] map = new String[]{"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};

        List<String> res = new ArrayList<>();
        StringBuilder lettersCombination = new StringBuilder();

        backTracking(map, digits, 0, res, lettersCombination);

        return res;

    }

    private void backTracking(String[] map, String digits ,int index,List<String> res, StringBuilder lettersCombination){

        if(index == digits.length()){
            // 加入结果集
            res.add(new String(lettersCombination.toString()));
            return;
        }

        String mapping = map[digits.charAt(index) - '0'];

        for(int i = 0; i < mapping.length(); i++){
            lettersCombination.append(mapping.charAt(i));
            backTracking(map, digits, index + 1, res, lettersCombination);
            lettersCombination.deleteCharAt(lettersCombination.length() - 1);
        }

    }
}