题目:
给定集合,求该集合的子集,如集合{1,2,3}的子集为:空集、{1}、{2}、{3}、{1,2}、{1,3}、{2,3}、{1,2,3},共2^3(即8)个子集。
以下使用递归解法求子集:
源码
public ArrayList<ArrayList<Integer>> subSet(int[] arr){
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
//添加空集
result.add(null);
ArrayList<Integer> list = new ArrayList<>();
subSetUtil(arr,result,list,0);
return result;
}
public void subSetUtil(int[] arr,ArrayList<ArrayList<Integer>> result,ArrayList<Integer>list,int index){
//遍历数组
for(int i=index;i<arr.length;i++){
list.add(arr[i]);
//递归中新建列表复制当前列表值
ArrayList<Integer> newlist = new ArrayList<>();
newlist.addAll(list);
//将复制的列表添加到返回值中
result.add(newlist);
subSetUtil(arr,result,list,i+1);
//每次递归返回时,删除添加的元素
list.remove(list.size()-1);
}
}
实现逻辑
集合{1,2,3}的子集可以拆分为每个元素为第一元素的组合,如1为第一元素的集合:{1},{1,2},{1,3}{1,2,3};
参数:
- 数组arr;
- 结果集result;
- 存放元素集list;
- 索引index
递归逻辑:
从数组的index位置开始继续遍历,然后将元素存放到list中,新建集合newlist作为子集,将list中的元素都添加到newlist,将子集存放结果集result,然后进行递归,索引index变为index+1;递归返回时,删除当前递归中添加到list的元素
下面以集合{1,2,3}为例子:
index=0;
进行遍历,i=0
list添加arr[i]元素,新建newlist使用addAll复制list的元素,result添加newlist,进行递归,传入index=(i+1)=1,list=[1]
index=1;
进行遍历,i=1;
list添加arr[i]元素,新建newlist使用addAll复制list的元素,result添加newlist,进行递归,传入index=(i+1)=2,list=[1,2]
index=2;
进行遍历,i=2
list添加arr[i]元素,新建newlist使用addAll复制list的元素,result添加newlist,进行递归,传入index=(i+1)=3,list=[1,2,3]
index=3;
大于数组的长度不进行遍历和递归,返回上一层递归;
index=2,i=2;
remove这一层插入的数据arr[i]=3;
list=[1,2],i=3不进行遍历,返回上一层递归;
index=1,i=1;
remove这一层插入的数据arr[i]=2;
i++;
进行遍历,i=2;
list添加arr[i]元素,新建newlist使用addAll复制list的元素,result添加newlist,进行递归,传入index=(i+1)=3,list=[1,3]
index=3;
不进行遍历,返回上一层递归;
index=1,i=2;
remove这一层插入的数据arr[i]=3;
遍历结束,返回上一层;
index=0;
remove这一层插入的数据arr[i]=1;
index=0;
进行遍历,i=1;
list添加arr[i]元素,新建newlist使用addAll复制list的元素,result添加newlist,进行递归,传入index=(i+1)=2,list=[2]
index=2,
进行遍历,i=2;
list添加arr[i]元素,新建newlist使用addAll复制list的元素,result添加newlist,进行递归,传入index=(i+1)=3,list=[2,3]
index=3;
大于数组的长度不进行遍历和递归,返回上一层递归;
index=2,i=2;
remove这一层插入的数据arr[i]=3;
list=[2],i=3不进行遍历,返回上一层递归;
index=0,i=1;
remove这一层插入的数据arr[i]=2;
index=0;
进行遍历,i=2;
list添加arr[i]元素,新建newlist使用addAll复制list的元素,result添加newlist,进行递归,传入index=(i+1)=3,list=[3]
index=3;
大于数组的长度不进行遍历和递归,返回上一层递归;
index=0,i=2;
remove这一层插入的数据arr[i]=3;
结束遍历,返回result;