题目
求一个数组的全部子集 一个常见的情景是罗列出[1,2,5,8]的全部子集,结果如下[],[1],[2],[5],[8],[1,2].................
题解
方法1
思想
利用递归; 遇到1,分为进入子集和不进入子集两类情况,进入递归; 继续判断2; ......
代码
//数组子集1
//ans存储结果;p为当前下标;array为给定数组,list为列表
public void arrayChild(List<List<Integer>> ans,int p,int[] array,List<Integer> list){
if (p==array.length){ //判断完数组,存储结果
ans.add(new ArrayList<>(list));
return;
}
arrayChild(ans,p+1,array,list); //当前下标不参与子串
list.add(array[p]);
arrayChild(ans,p+1,array, list); //当前下标参与字串
list.remove(list.size()-1); //这里要对添加后的数据进行删除,避免影响list递归
}
方法2
思想
利用二进制;
根据数组位数,设置最大二进制数,比如[1,2,5,8], 对应二进制数:1111(2^4);[1,4,6],对应:111 (2^3);
根据最大二进制数依次遍历,[1,2,5,8]为例,从0000遍历到1111,对号入座,比如0101,即对应子集[2,8], 0011对应子集[ 5,8], 0000对应子集 []
代码
//数组子集2
public List<List<Integer>> arrayChild2(int[] array){
List<List<Integer>> ans=new ArrayList<>();
int length=array.length;
long max= (long) Math.pow(2,length); //最大值
System.out.println(max);
for(int i=0;i<max;i++){
ArrayList<Integer> list=new ArrayList<>();
String num=Integer.toBinaryString(i); //转为二进制
for (int j=0;j<num.length();j++){ //处理当前值
if (num.charAt(num.length()-1-j)!='0'){
list.add(array[length-1-j]);
}
}
ans.add(new ArrayList<>(list)); //结果添加到ans
}
return ans;
}