216.组合总和III
● 力扣题目链接
● 找出所有相加之和为 n 的 k 个数的组合。组合中只允许含有 1 - 9 的正整数,并且每种组合中不存在重复的数字。
思路
● 和上题差不多,只不过多了一个条件限制
● 时间复杂度:O(n * 2^n)
代码
class Solution {List<List<Integer>> res = new ArrayList();LinkedList<Integer> path = new LinkedList();public List<List<Integer>> combinationSum3(int k, int n) {combinationSum3Helper(k, n, 1, 0);return res;}private void combinationSum3Helper(int k, int n, int startIndex, int sum) {if (sum > n) return; // 一旦sum大了,直接返回if (path.size() == k) { // 达到size要求if (sum == n) { // 如果sum符合要求,才加入res.add(new ArrayList<>(path));}return; // 不然直接return}for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++) { // for循环遍历本层sum += i;path.addFirst(i);combinationSum3Helper(k, n, i + 1, sum); // 递归遍历深度sum -= i;path.removeFirst();}}
}
17.电话号码的字母组合
● 力扣题目链接
● 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
思路
● 我们先用一个数组,存储数字和对应字符的关系
● 假如输入的是23,我们先看看输入的是不是空,是空直接返回,否则进入回溯函数,使用一个startIndex标记遍历到了这个数组的哪个位置
● 如果startIndex走到了最后,说明找到了一个结果
● 否则开始本层的循环(就是这个数字对应的字符循环),使用StringBuilder标记,取了之后进入下一层递归,要看下一个数字的情况,因此传入的是startIndex + 1
● 时间复杂度: O(3^m * 4^n),其中 m 是对应四个字母的数字个数,n 是对应三个字母的数字个数
代码
class Solution {List<String> res = new ArrayList();StringBuilder builder = new StringBuilder();String[] numString = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};public List<String> letterCombinations(String digits) {if (digits == null || digits.length() == 0) return res;letterCombinationsHelper(digits, 0);return res;}private void letterCombinationsHelper(String digits, int startIndex) {if (startIndex == digits.length()) {res.add(new String(builder));return;}String str = numString[digits.charAt(startIndex) - '0'];for (int i = 0; i < str.length(); i++) {builder.append(str.charAt(i));letterCombinationsHelper(digits, startIndex + 1);builder.deleteCharAt(builder.length() - 1);}}
}