代码随想录算法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 }

 

 

posted @ 2023-02-25 19:41  颜欢兮  阅读(24)  评论(0)    收藏  举报