算法训练Day25|216.组合总和III● 17.电话号码的字母组合

简介: 算法训练Day25|216.组合总和III● 17.电话号码的字母组合

LeetCode:  216.组合总和III

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


1.思路

结果集收集每个结果,被函数调用需要声明全局变量result和path。

递归法进行广度和深度遍历,深度遍历k层,广度遍历受限于9的数值。传递参数startIndex用以记录每层递归开始的位置。另外,三个参数的传递更方便。


2.代码实现

 1// 传入四个参数
 2class Solution {
 3    List<List<Integer>> result = new ArrayList<>(); // 收集结果的集合
 4    LinkedList<Integer> path = new LinkedList<>(); // 收集结果集
 5    public List<List<Integer>> combinationSum3(int k, int n) {
 6        backtracking(k, n, 1, 0); 
 7        return result;
 8    }
 9
10    public void backtracking(int k, int n, int startIndex, int sum) {
11        // sum 大于 n 时,剪枝操作return
12        if (sum > n) {
13            return;
14        }
15        // 长度大于 k 时, 剪枝操作return 
16        if (path.size() > k) {
17            return;
18        }
19        // 当长度和总和均满足要求,则将path加入结果集中
20        if (sum == n && path.size() == k) {
21            result.add(new ArrayList<>(path));
22            return;
23        }
24        // for循环进行深度和广度的遍历
25        for (int i = startIndex; i <= 9; i++) {
26            sum += i;
27            path.add(i);
28            backtracking(k, n, i + 1, sum);
29            sum -= i; // 回溯剪枝
30            path.removeLast(); // 回溯剪枝
31        }
32    }
33}
34
35// 传入三个参数可能更容易想到
36class Solution {
37    List<List<Integer>> result = new ArrayList<>(); // 收集结果的集合
38    LinkedList<Integer> path = new LinkedList<>(); // 收集结果集
39    public List<List<Integer>> combinationSum3(int k, int n) {
40        backtracking(k, n, 1); 
41        return result;
42    }
43
44    public void backtracking(int k, int n, int startIndex) {
45        // sum 大于 n 时,剪枝操作return
46        if (n < 0 ) {
47            return;
48        }
49        // 长度大于 k 时, 剪枝操作return 
50        if (path.size() > k) {
51            return;
52        }
53        // 当长度和总和均满足要求,则将path加入结果集中
54        if (0 == n && path.size() == k) {
55            result.add(new ArrayList<>(path));
56            return;
57        }
58        // for循环进行深度和广度的遍历
59        for (int i = startIndex; i <= 9; i++) {
60            n -= i;
61            path.add(i);
62            backtracking(k, n, i + 1);
63            n += i; // 回溯剪枝
64            path.removeLast(); // 回溯剪枝
65        }
66    }
67}

3.复杂度分析

时间复杂度:O(n*n^2).一次递归查值(深度)对应k次递归和k次for循环,则时间消耗为n^2,n次遍历(广度)则需要n.

空间复杂度:O(k).空间复杂度取决于栈和堆空间的消耗,栈时是递归函数调用的层数k,数组则为O(k).


LeetCode: 17.电话号码的字母组合

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


1.思路

题意:在一个集合中,选取符合条件的两个元素可能的组合结果。

map映射映或者二维数组均可以存储相应的元素,回溯函数传入需要的参数:digits/numString/num对其进行递归即可.


2.代码实现

 1class Solution {
 2
 3    List<String> list = new ArrayList<>(); // 存储最终结果的列表
 4    StringBuilder temp = new StringBuilder(); // 创建字符串???
 5
 6    public List<String> letterCombinations(String digits) {
 7        if (digits == null || digits.length() == 0) { // 数字字符串为空或长度为0 时直接返回
 8            return list;
 9        }
10        String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; // 为每个数字对应的字母构建字符数组
11        backTracking(digits, numString, 0); // 递归函数,传入数字字符串digits,字符数组numString, 以及遍历开始位置
12        return list;
13
14    }
15    // 回溯函数
16    public void backTracking(String digits, String[] numString, int num) {
17        // 遍历长度num 等于 数字字符串dights的长度时,将结果转化为字符数组加入list中即可
18        if (num == digits.length()) {
19            list.add(temp.toString()); // 将对象temp转化为字符串表示形式
20            return; 
21        }
22        String str = numString[digits.charAt(num) - '0']; // 获取当前数字对应的字母表
23        for (int i = 0; i < str.length(); i++) { // 遍历字母表中的每个字母
24            temp.append(str.charAt(i)); // 将当前字母加入到临时字符串
25            backTracking(digits, numString, num + 1); // 递归调用下一个数字的回溯
26            temp.deleteCharAt(temp.length() - 1); // 递归符合条件之后,删除临时字符串的最后一个字母,进行下一个字母的调用
27        }
28    }
29}

3.复杂度分析

时间复杂度:O(n*2^k).

空间复杂度:O(k+m).k为递归函数的深度或层数,k为字符数组的大小.


相关文章
|
4天前
|
算法 测试技术 C#
【多数组合 数学 字符串】2514. 统计同位异构字符串数目
【多数组合 数学 字符串】2514. 统计同位异构字符串数目
|
7月前
|
算法
代码随想录Day21 回溯 LeetCodeT216 组合总和III LeetCode T17电话号码的字母总和
代码随想录Day21 回溯 LeetCodeT216 组合总和III LeetCode T17电话号码的字母总和
31 0
|
7月前
代码随想录Day22 LeetCode T39 组合总和 T40 组合总和II T131 分割回文串
代码随想录Day22 LeetCode T39 组合总和 T40 组合总和II T131 分割回文串
20 0
|
9月前
|
算法
算法训练Day27|39. 组合总和● 40.组合总和II● 131.分割回文串
算法训练Day27|39. 组合总和● 40.组合总和II● 131.分割回文串
|
9月前
|
算法
算法训练Day34|1005.K次取反后最大化的数组和 ● 134. 加油站● 135. 分发糖果
算法训练Day34|1005.K次取反后最大化的数组和 ● 134. 加油站● 135. 分发糖果
|
9月前
|
算法 索引
算法训练Day36|435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间
算法训练Day36|435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间
|
10月前
|
算法
|
11月前
|
存储 算法 Java
代码随想录训练营day25| 216.组合总和III 17.电话号码的字母组合
代码随想录训练营day25| 216.组合总和III 17.电话号码的字母组合
|
11月前
|
算法 Java 网络架构
代码随想录训练营day27| 39. 组合总和 40.组合总和II 131.分割回文串
代码随想录训练营day27| 39. 组合总和 40.组合总和II 131.分割回文串
|
12月前
|
C++
C/C++每日一练(20230502) 卖树苗、数字归类、组合总和II
C/C++每日一练(20230502) 卖树苗、数字归类、组合总和II
101 0