- 时间:2020-07-27
- 题目链接:https://leetcode-cn.com/problems/combinations
- tag:
回溯
给定两个整数 n 和 k,返回 1 ... n 中所有可能的 k 个数的组合。
示例:
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
典型回溯法的题目,注意剪枝条件可以参考这里
class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> result = new ArrayList<>();
backtracking(n, k, 1, new ArrayList<Integer>(), result);
return result;
}
private void backtracking(int n, int k, int start, List<Integer> temp, List<List<Integer>> result) {
if (k == temp.size()) {
result.add(new ArrayList<Integer>(temp));
return;
}
for (int i = start; i <= n - (k - temp.size()) + 1 ; i++) { // 注意这里的剪枝条件,不要写成i <= n,没有必要
temp.add(i);
backtracking(n, k, i + 1, temp, result);
temp.remove(temp.size() - 1);
}
}
}
这个看着很厉害,但其实没有剪枝后的回溯快
class Solution {
public List<List<Integer>> combine(int n, int k) {
// init first combination
LinkedList<Integer> nums = new LinkedList<Integer>();
for(int i = 1; i < k + 1; ++i)
nums.add(i);
nums.add(n + 1);
List<List<Integer>> output = new ArrayList<List<Integer>>();
int j = 0;
while (j < k) {
// add current combination
output.add(new LinkedList(nums.subList(0, k)));
// increase first nums[j] by one
// if nums[j] + 1 != nums[j + 1]
j = 0;
while ((j < k) && (nums.get(j + 1) == nums.get(j) + 1))
nums.set(j, j++ + 1);
nums.set(j, nums.get(j) + 1);
}
return output;
}
}