一、题目:77. 组合
二、题目解析
返回1-n之间,k个数的组合,改题属于经典的回溯解决法。
先选一个数字,然后开始进入递归继续选,满足条件后k=2加到结果集中,然后通过剪枝回到上一步,继续递归。
图示帮助理解:
三、代码如下:
public List<List<Integer>> combine(int n,int k){
List<List<Integer>> res = new ArrayList<>();
backTracking(n,k,res,1,new ArrayList<Integer>());
return res;
}
/**
* @param n: 每次都要从1-n之间进行遍历
* @param k: k是递归终止条件
* @param res: 在递归里面一旦检测到满足条件的组合就加入结果中
* @param start: 代表从某一个树开始查,---(查完1为根节点的树,再查以2为根节点的树 )
* @param temp: 临时集合存储结果
**/
private void backTracking(int n,int k,List<List<Integer>> res,int start,ArrayList<Integer> temp) {
//一旦长度满足k说明,满足条件了
if(temp.size()==k){
//将temp复制到一个新的list,为什么要复制? 避免引用传递
res.add(new ArrayList<Integer>(temp));
return;
}
//从 start 到 n
for (int j = start; j <=n ; j++) {
//将当前数字加入temp
temp.add(j);
//进行递归 j+1是新 的开始条件
backTracking(n,k,res,j+1,temp);
//俗称剪枝 将当前数组删除,进入下次for 循环
//为啥要remove?
//假如以1为根结点找到【1,2】,返会上一层的时候不能把2带回去,否则,下次以1为根节点遍历就拿到了【1,2,3】,这样是不对的
temp.remove(temp.size()-1);
}
}
四、测试
五、结束