- 题目描述
给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。
来源:LeetCode
- 示例
- 示例:
输入: n = 4, k = 2
输出:
[
[2,4],
[3,4],
[2,3],
[1,2],
[1,3],
[1,4],
]
- 思路分析
回溯+剪枝,列举所有情况即可。这道题很容易可以用回溯得到所有答案,但如果不剪枝,效率很低。这里剪枝主要是通过观察发现:如果剩下的元素加起来都没有 k k k个,是不可能有满足条件的组合的。 k < = k <= k<= 已经排列的数+正在排的数+数组中剩下的数 < = l i s t . s i z e ( ) + 1 + n − i <= list.size()+1+n-i <=list.size()+1+n−i,所以 i < = n + 1 + l i s t . s i z e ( ) − k i<=n+1+list.size()-k i<=n+1+list.size()−k即为剪枝条件。
- JAVA实现
class Solution {
public List<List<Integer>> combine(int n, int k) {
int num = 1;
List<Integer> temp = new ArrayList();
List<List<Integer>> res = new ArrayList();
tb(temp, res, num, n, k);
return res;
}
public void tb(List<Integer> temp, List<List<Integer>> res, int num, int n, int k) {
if(temp.size()==k) { //已经达到了规定个数
res.add(new ArrayList(temp));
return;
}
for(int i=num; i<=n+temp.size()-k+1; i++) { //这里的剪枝很重要
temp.add(i);
tb(temp, res, i+1, n, k);
temp.remove(temp.size()-1); //回溯,去掉这一轮加入的数
}
}
}