这道题目一看我,我的第一想法就是递归
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> alllist=new ArrayList<>();
alllist.add(new ArrayList<Integer>());
for(int i=1;i<=nums.length;i++){
getanswer(alllist,new ArrayList<>(),nums,i,0);
}
return alllist;
}
public void getanswer(List<List<Integer>> listall,List<Integer> list,int[] nums,int n,int start){n是子集的元素个数,start是遍历时,子集元素的下标
if(n==0){//当n==0时,则跳出递归
listall.add(list);
return;
}
for(int i=start;i<nums.length-n+1;i++){
ArrayList<Integer> temp=new ArrayList<>(list);//创建一个临时的list,用来保存新的结果
temp.add(nums[i]);
getanswer(listall,temp,nums,n-1,i+1);
}
}
假设数组为[1,2,3]----
先求元素个数为 1 的子集,则n等于1
则递归一次就会跳出循环。此时allList=[[1],[2],[3]];
第二次n=2
**list=[1] ,n=n-1=1—>list1=[1,2] list2=[1,3] n=n-1=0 —> alllist.add(list1) add(list2)
**list=[2] ,n=n-1=1 —>list1=[2,3] n=n-1=0 —> allllist.add(list1)
**list=[3] n=n-1=1 —>start=2, start+n=2+2=4<nums.length 结束
第三次 n=3
list=[1] n=n-1=2; -->list=[1,2] n=n-1=1;–>list[1,2,3] n=n-1=0 allList.add(list);
list=[2] i=1 i+n=4>nums.length 结束
后来看了评论区 有更好的方法
遍历一次数组,每次遍历的时候,就把之前生成的list集合复制,并添加当前遍历到值。
public List<List<Integer>> subsets(int[] nums) {//方法二
List<List<Integer>> alllist=new ArrayList<>();
for(int i=0;i<nums.length;i++){
for(int j=0,size=alllist.size();j<size;j++){
List<Integer> copy=new ArrayList<>(alllist.get(j));
copy.add(nums[i]);
alllist.add(copy);
}
ArrayList<Integer> temp=new ArrayList<>();
temp.add(nums[i]);
alllist.add(temp);
}
alllist.add(new ArrayList<>());
return alllist;
}
以[1,2,3]为例
i=0 listall=[[1]]
i=1 listall=[[1],[1,2],[2]];
i=2 listall=[[1][1,2],[2],[1,3],[1,2,3][2,3],[3]]