77. 组合
难度:中等
题目描述
解题思路
1、自己写的憨憨思路
就是用全排列的代码+剪枝,每次只往里面添加更大的数字
但是其实可以不用这样
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> res = new LinkedList<>();
if(n == 0 || k == 0)
return res;
boolean[] visit = new boolean[n+1];
List<Integer> temp = new LinkedList<>();
combineHelper(n, k,res,temp,visit,1);
return res;
}
public void combineHelper(int n, int k,List<List<Integer>> res,List<Integer> temp,boolean[] visit,int cur) {
if(temp.size() == k) {
res.add(new LinkedList<>(temp));
return;
}
for (int i = cur; i <= n; i++) {
if(!visit[i] && (temp.size() == 0 || i > temp.get(temp.size()-1))) {
temp.add(i);
visit[i] = true;
combineHelper(n, k,res,temp,visit,cur+1);
visit[i] = false;
temp.remove(temp.size()-1);
}
}
}
2、另外的写法
基本思路也是回溯+剪枝,但是这个不是全排列,所以不需要每次从1开始,从上一个选择+1开始就可以了,另外每次开始回溯的时候也可以设置一个上届。如果剩下数据的长度加起来没办法组合成一个组合,就不开始回溯的过程
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> res = new LinkedList<>();
if(n == 0 || k == 0)
return res;
List<Integer> temp = new LinkedList<>();
combineHelper(n, k,res,temp,1);
return res;
}
public void combineHelper(int n, int k,List<List<Integer>> res,List<Integer> temp,int cur) {
if(temp.size() == k) {
res.add(new LinkedList<>(temp));
return;
}
for (int i = cur; i <= n - (k - temp.size())+1; i++) {
temp.add(i);
combineHelper(n, k,res,temp,i+1);
temp.remove(temp.size()-1);
}
}