代码随想录算法Day25 | 216.组合总和III, 17.电话号码的字母组合
216.组合总和III
题目链接:216. 组合总和 III - 力扣(LeetCode)
思路
本题思路与 77.组合 差不多,加个限制条件即可解决。
选取过程如图:

代码
1 class Solution { 2 List<List<Integer>> result = new ArrayList<>(); 3 LinkedList<Integer> path = new LinkedList<>(); 4 5 public List<List<Integer>> combinationSum3(int k, int n) { 6 backTracking(n, k, 1, 0); 7 return result; 8 } 9 10 private void backTracking(int targetSum, int k, int startIndex, int sum) { 11 // 减枝 12 if (sum > targetSum) { 13 return; 14 } 15 16 if (path.size() == k) { 17 if (sum == targetSum) result.add(new ArrayList<>(path)); 18 return; 19 } 20 21 // 减枝 9 - (k - path.size()) + 1 22 for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) { 23 path.add(i); 24 sum += i; 25 backTracking(targetSum, k, i + 1, sum); 26 //回溯 27 path.removeLast(); 28 //回溯 29 sum -= i; 30 } 31 } 32 } 33 34 // 上面剪枝 i <= 9 - (k - path.size()) + 1; 如果还是不清楚 35 // 也可以改为 if (path.size() > k) return; 执行效率上是一样的 36 class Solution { 37 LinkedList<Integer> path = new LinkedList<>(); 38 List<List<Integer>> ans = new ArrayList<>(); 39 public List<List<Integer>> combinationSum3(int k, int n) { 40 build(k, n, 1, 0); 41 return ans; 42 } 43 44 private void build(int k, int n, int startIndex, int sum) { 45 46 if (sum > n) return; 47 48 if (path.size() > k) return; 49 50 if (sum == n && path.size() == k) { 51 ans.add(new ArrayList<>(path)); 52 return; 53 } 54 55 for(int i = startIndex; i <= 9; i++) { 56 path.add(i); 57 sum += i; 58 build(k, n, i + 1, sum); 59 sum -= i; 60 path.removeLast(); 61 } 62 } 63 }
17.电话号码的字母组合
题目链接:17. 电话号码的字母组合 - 力扣(LeetCode)
思路
1、解决数字映射问题,可以使用map或者定义一个二维数组,例如:string letterMap[10],来做映射。
2、随后用回溯法解决n个for循环的问题,过程如图。

3、最后要注意 输入1 * #按键等异常的情况。
代码
1 class Solution { 2 3 //设置全局列表存储最后的结果 4 List<String> list = new ArrayList<>(); 5 6 public List<String> letterCombinations(String digits) { 7 if (digits == null || digits.length() == 0) { 8 return list; 9 } 10 //初始对应所有的数字,为了直接对应2-9,新增了两个无效的字符串"" 11 String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; 12 //迭代处理 13 backTracking(digits, numString, 0); 14 return list; 15 16 } 17 18 //每次迭代获取一个字符串,所以会设计大量的字符串拼接,所以这里选择更为高效的 StringBuild 19 StringBuilder temp = new StringBuilder(); 20 21 //比如digits如果为"23",num 为0,则str表示2对应的 abc 22 public void backTracking(String digits, String[] numString, int num) { 23 //遍历全部一次记录一次得到的字符串 24 if (num == digits.length()) { 25 list.add(temp.toString()); 26 return; 27 } 28 //str 表示当前num对应的字符串 29 String str = numString[digits.charAt(num) - '0']; 30 for (int i = 0; i < str.length(); i++) { 31 temp.append(str.charAt(i)); 32 //c 33 backTracking(digits, numString, num + 1); 34 //剔除末尾的继续尝试 35 temp.deleteCharAt(temp.length() - 1); 36 } 37 } 38 }

浙公网安备 33010602011771号