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

84 阅读1分钟

216. Combination Sum III

Find all valid combinations of k numbers that sum up to n such that the following conditions are true:

  • Only numbers 1 through 9 are used.
  • Each number is used at most once.

Return a list of all possible valid combinations. The list must not contain the same combination twice, and the combinations may be returned in any order.

 

Example 1:

Input: k = 3, n = 7
Output: [[1,2,4]]
Explanation:
1 + 2 + 4 = 7
There are no other valid combinations.

Example 2:

Input: k = 3, n = 9
Output: [[1,2,6],[1,3,5],[2,3,4]]
Explanation:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
There are no other valid combinations.

Example 3:

Input: k = 4, n = 1
Output: []
Explanation: There are no valid combinations.
Using 4 different numbers in the range [1,9], the smallest sum we can get is 1+2+3+4 = 10 and since 10 > 1, there are no valid combination.

 

Constraints:

  • 2 <= k <= 9
  • 1 <= n <= 60

回溯法,不难写。剪枝操作绕了一会。结果是用 9 - 当前元素 + 1 > k - path.size(),即可用的数字 > 需要的数字来写,且判断发生在将当前循环元素加入递归之前,所以带个 +1

class Solution {
    public void backtracking(LinkedList<Integer> path, int k, int n, int sum, int start, List<List<Integer>> res) {
        if(path.size() == k) {
            if(sum == n) {
                res.add(new ArrayList<Integer>(path));
            }
            return;
        }

        for(int i=start; i<=9 && (9 - i + 1) >= (k - path.size()); i++) {
            path.add(i);
            backtracking(path, k, n, sum + i, i+1, res);
            path.removeLast();
        }

    }
    public List<List<Integer>> combinationSum3(int k, int n) {
        LinkedList<Integer> path = new LinkedList<Integer>();
        List<List<Integer>> res = new LinkedList<List<Integer>>();

        backtracking(path, k, n, 0, 1, res);

        return res;
    }
}

17. Letter Combinations of a Phone Number

Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. Return the answer in any order.

A mapping of digits to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.

 

Example 1:

Input: digits = "23"
Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"]

Example 2:

Input: digits = ""
Output: []

Example 3:

Input: digits = "2"
Output: ["a","b","c"]

 

Constraints:

  • 0 <= digits.length <= 4
  • digits[i] is a digit in the range ['2', '9'].

这题感觉写麻烦了一些,如果定义一个字符串数组,把数值map到可选字符串会简单一些。 但用switch case是比较容易处理异常字符。代码本身没考虑异常字符,考虑的话,要把default的处理改动下,移到上面的case里。用default逻辑来处理异常字符。

class Solution {
    public void backtracking(StringBuilder sb, int pos, char[] digits, List<String> res) {


        if(sb.length() == digits.length) {

            if(sb.length() > 0) {
                res.add(new String(sb.toString()));
            }
            return;
        }
       
        int cur = digits[pos] - '0'; //get digit number
        if(cur == 1) {
            //skip current
            backtracking(sb, pos+1, digits, res);
        }
        else if (cur>=2 && cur<=9) {
            //23456789
            int num =0;
            int start = 0;

            switch(cur) {
                case 7:
                    num = 4;
                    start = 15;
                    break;
                case 8:
                    num = 3;
                    start = 19;
                    break;
                case 9:
                    num = 4;
                    start = 22;
                    break;
                default:
                    num = 3;
                    start = (cur-2) * 3;
            }

            for(int i=0; i<num; i++) {
                char cc = (char)('a' + start + i);
                sb.append(cc);

                backtracking(sb, pos+1, digits, res);
                sb.deleteCharAt(sb.length() - 1);
            }
        }
        else {
            return;
        }
    }
    public List<String> letterCombinations(String digits) {
        List<String> res = new ArrayList<String>();
        char[] ad = digits.toCharArray();
        StringBuilder sb = new StringBuilder();
        System.out.println(ad.length);

        backtracking(sb, 0, ad, res);

        return res;
    }
}