【LeetCode】78. 子集

78. 子集

知识点:数组;位运算;

题目描述

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。

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

输入:nums = [0]
输出:[[],[0]]

解法一:迭代

这道题目可以用迭代的方式去解,首先在答案中添加空集,然后每遍历一个元素,就是把答案中已有的集合在,末尾追加元素。比如例1,遍历1的时候,在空集后追加1.遍历2的时候在答案中的集合空集和1后追加2,形成2和1,2;依次类推;

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> list = new ArrayList<>();
        res.add(list);
        for(int num : nums){
            for(int i = 0; i < res.size(); i++){
                List<Integer> temp = new ArrayList<>(res.get(i));
                temp.add(num);  //在每个集合后添加新元素;
                res.add(temp);
            }
        }
        return res;
    }
}

解法二:位运算

有3个元素,那最后我们得到的子集个数一定是8个,也就是2^3个,想一下我们其实可以用3位的0,1二进制表示,哪一位上为1就对应哪一位上被选中,比如001,代表3,011代表2,3,000代表空集;这样就把所有的子集都找到了。

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        int n = nums.length;
        int len = 1 << n;  //一共有多少个子集;
        List<List<Integer>> res = new ArrayList<>();
        for(int i = 0; i < len; i++){  //遍历所有长度的数字,根据数字中的位置来找子集
            List<Integer> list = new ArrayList<>();
            for(int j = 0; j < n; j++){
                if(((i >> j) & 1) != 0){  //将数字依次右移,选出不为零的,也就是为1的;
                    list.add(nums[j]);  //哪位上为1选中哪位;
                }
            }
            res.add(list);
        }
        return res;
    }
}
posted @ 2021-08-13 22:16  Curryxin  阅读(158)  评论(4编辑  收藏  举报
Live2D