1. 组合
77. 组合https://leetcode.cn/problems/combinations/
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。
你可以按 任何顺序 返回答案。
示例 1:
输入:n = 4, k = 2
输出:
[[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],
]
示例 2:
输入:n = 1, k = 1
输出:[[1]]
解题思路
这种涉及到穷举的题,第一反应都是回溯实现。
考虑回溯三要素:
- 回溯逻辑:每次都从i到进行循环,循环中进行递归
- 终止条件:当k=0的时候,说明取完k个数了,终止,当i大于n的时候,说明取值不符合了,也终止
- 参数:一个k表示还需要取的个数,一个n表示边界,一个i表示当前取值的开始边界
这样子是借助于回溯实现了暴力for循环。考虑进行优化:
在每次回溯算法的逻辑中,从i开始到n,如果i到n已经不够k个的时候,已经是无效了,可以直接终止;
代码
class Solution {List<List<Integer>> result = new ArrayList<>();LinkedList<Integer> list = new LinkedList<>();public List<List<Integer>> combine(int n, int k) {backtracking(k, n, 1);return result;}public void backtracking(int k, int n, int i) {if (k == 0) {result.add(new ArrayList<>(list));return;}if (n - i + 1 < k)return;if (i > n)return;for (; i <= n; i++) {list.add(i);backtracking(k - 1, n, i + 1);list.removeLast();}}
}
2. 组合总和III
216. 组合总和 IIIhttps://leetcode.cn/problems/combination-sum-iii/
找出所有相加之和为 n
的 k
个数的组合,且满足下列条件:
- 只使用数字1到9
- 每个数字 最多使用一次
返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次,组合可以以任何顺序返回。
示例 1:
输入: k = 3, n = 7
输出: [[1,2,4]]
解释:
1 + 2 + 4 = 7
没有其他符合的组合了。
示例 2:
输入: k = 3, n = 9
输出: [[1,2,6], [1,3,5], [2,3,4]]
解释:
1 + 2 + 6 = 9
1 + 3 + 5 = 9
2 + 3 + 4 = 9
没有其他符合的组合了。
示例 3:
输入: k = 4, n = 1
输出: []
解释: 不存在有效的组合。
在[1,9]范围内使用4个不同的数字,我们可以得到的最小和是1+2+3+4 = 10,因为10 > 1,没有有效的组合。
解题思路
使用回溯实现暴力for循环。
终结条件:k等于0的时候,终止,如果sum和n相等就加入result。
参数:k,n,sum,i
回溯逻辑:从i到9进行循环,在循环中进行递归。
剪枝优化:当sum已经大于result的时候,终止。当9-i+1<k的时候也终止。
代码
class Solution {List<List<Integer>> result = new ArrayList<>();LinkedList<Integer> list = new LinkedList<>();public List<List<Integer>> combinationSum3(int k, int n) {combinationHelper(k, n, 0, 1);return result;}private void combinationHelper(int k, int targetSum, int sum, int i) {if (k == 0 && targetSum == sum) {result.add(new ArrayList<>(list));return;}if (9 - i + 1 < k || sum > targetSum)return;for (; i <= 9; i++) {list.add(i);combinationHelper(k - 1, targetSum, sum + i, i + 1);list.removeLast();}}
}
3. 电话号码的字母组合
17. 电话号码的字母组合https://leetcode.cn/problems/letter-combinations-of-a-phone-number/
给定一个仅包含数字 2-9
的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例 1:
输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = ""
输出:[]
示例 3:
输入:digits = "2"
输出:["a","b","c"]
解题思路
使用回溯来完成for循环。
代码
class Solution {List<String> result = new ArrayList<>();String[] letters = new String[] { "", " ", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };StringBuilder segment = new StringBuilder();public List<String> letterCombinations(String digits) {if (digits == null || digits.equals(""))return result;letterCombinationsHelper(digits, 0);return result;}public void letterCombinationsHelper(String digits, int i) {if (i == digits.length()) {result.add(segment.toString());return;}String temp = letters[digits.charAt(i) - '0'];for (int j = 0; j < temp.length(); j++) {segment.append(temp.charAt(j));letterCombinationsHelper(digits, i + 1);segment.deleteCharAt(segment.length() - 1);}}}