集合中元素组合的所有可能
:集合中的数据不重复,需要穷举,可以采用递归+回溯
的方法;分析回溯算法,常常需要画图来帮助我们理清思路和寻找边界问题:递归什么时候截止
,什么时候可以进行剪枝
package BDyNamicProgramming;
import java.util.ArrayList;
import java.util.List;
/**
* @Author Zhou jian
* @Date 2020 ${month} 2020/4/25 0025 14:18
*/
public class Problem77 {
/**
* 返回1,2,3.....n数中,组成k个数的所有可能情况
* @param n
* @param k
* @return
*/
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> rs = new ArrayList<>();
List<Integer> path = new ArrayList<>();
fun(n,k,rs,path,0);
return rs;
}
/**
*
* @param n 待取的数
* @param k 还剩取的数的个数 (若k==0)则说明找到一个组合
* @param rs 存取最终存的结果
* @param path 存储遍历的过程中的路径
* @param begin 搜索的起始路径(这很关键
* 组合(元素可以重复 元素不可以重复)
*
* 排列(
*/
public void fun(int n,int k,List<List<Integer>> rs,List<Integer> path,int begin){
//组成一个组合
if(k==0){
rs.add(new ArrayList<>(path));
return;
}
//进行递归查找:查找的位置从begin开始
for(int i=begin;i<n;i++){
//放这里提前一些,不用递归进去判断
//意思是,就算将i......n这 n - i + 1个数字都选到vec中,都不够k长度,则不用继续递归了
if(k -path.size() > n - i + 1)
return;
path.add(i+1);
//接下来查找的位置从其后面的一个位置开始查找(若可以取重复元素则可以从自身开始 其实位置为i)
fun(n,k-1,rs,path,i+1);
//进行回溯
path.remove((Object)(i+1));
}
}
}