78. Subsets

原题:

点击打开链接

即返回给定数组的所有子集。


思考过程&解题思路:

一开始想到用递归的办法(其实是深度优先遍历DFS);后来看到更高明的办法:位操作。其实一个集合子集数量就是2的(集合元素个数)次方。因为对于任何一个元素,在某个子集中要么有,要么没有。所以子集个数就是这个情况数。用二进制数字表示当前子集是否有数组某个元素。二进制数字中第n位为1表示当前子集有数组的第n个元素。


结果代码:

List<List<Integer>> ret = new ArrayList<>();
    public List<List<Integer>> subsetsDFS(int[] nums) {
        ret.add(new ArrayList<>());//先加上空集
        for (int i = 0;i < nums.length;i++){
            List<Integer> integers = new ArrayList<>();
            DFS(integers,i,nums);
        }
        return ret;
    }
    public void DFS(List<Integer> former,int begin,int nums[]){
        List<Integer> subRet = new ArrayList<>();
        subRet.addAll(former);
        subRet.add(nums[begin]);//把上次传来的结果集和第二个参数对应数组的元素传入新的结果子集中
        ret.add(subRet);//新的结果子集添加到结果集
        while (begin < nums.length - 1) DFS(subRet,++begin,nums);//关键在于这里,只往后递归,避免重复,逐个添加后面的元素,继续递归
    }

    public List<List<Integer>> subsets(int[] nums) {
        int len = nums.length;
        for (int i = 0;i < 1 << len;i++){//i的二进制数字中,第n位为0表示当前结果子集中没有数组第n个元素。为1表示有这个元素
            List<Integer> subRet = new ArrayList<>();
            for (int j = 0;j < len;j++){//j表示数组第j个元素
                if ((i & (1 << j)) != 0)//1向左移动j位后,和i作&运算,如果为0,说明i的第j位为0,否则为1
                    subRet.add(nums[j]);
            }
            ret.add(subRet);
        }
        return ret;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值