Leetcode笔记2

本文介绍如何使用位运算技巧高效地生成整数数组 nums 的所有子集(幂集),通过二进制编码和位与操作简化子集构造过程。实例演示了将000到111映射到不同子集的过程,并提供了Solution类的代码实现。
摘要由CSDN通过智能技术生成

题目:

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。
解集不能包含重复的子集。你可以按任意顺序返回解集。

示例 1:
输入:nums = [1,2,3] 输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

示例 2:
输入:nums = [0]
输出:[[],[0]]

此题有很多解法,但个人认为利用位运算比较好理解。针对不同的示例,我们可以得出这样的结论,即若数组nums的长度为n,则其子集一共有2 n ^{n} n个元素。由此我们联想到,是否可以通过编码即生成n位二进制数来为不同的子集元素进行编码呢?

000[ ]
001[3]
010[2]
011[2,3]
100[1]
101[1,3]
110[1,2]
111[1,2,3]

显然我们需要两层for循环,第一层用来遍历000~111,第二层用来遍历每个二进制编码中哪一位是1,将是1的那一位所对应nums中的值放入子集元素中。我的代码中所有的这些操作都是用的位运算,1<<n表示1左移n位即2 n ^{n} n1<<j表示1左移j位即2 j ^{j} j,但是j<n,因为对于三位二进制假如要判断011哪一位有1只能将其分别与001(2 0 ^{0} 0),010(2 1 ^{1} 1)和100(2 2 ^{2} 2)按位与。

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        int n=nums.length;
        List<List<Integer>> sub=new ArrayList<>();
        sub.add(new ArrayList<>());
        for(int i=1;i<(1<<n);i++){
            List<Integer> list=new ArrayList<>();
            for(int j=0;j<n;j++){
                if((i&(1<<j))>0)
                    list.add(nums[j]);
            }
            sub.add(list);
        }
        return sub;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值