coding: 求一个数组的全部子集

234 阅读1分钟

题目

求一个数组的全部子集 一个常见的情景是罗列出[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;
}