子集

130 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一、题目:

leetcode 子集

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

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

示例 1:

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

示例 2:

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

提示:

1 <= nums.length <= 10
-10 <= nums[i] <= 10
nums 中的所有元素 互不相同

二、题解:

1.解读 也就是需要返回nums所有的可能子集,因为元素都没有相同的,所以不用考虑重复元素了。

方法一 逐个枚举,先加入空的子集,然后遍历nums数组,每获取一个元素,就往之前的集合中追加上这个元素。

方法二

还有一种就是先取出nums数组的每个元素,然后把这个元素当做子集的第一个元素,再枚举剩余的可能。例如[1, 2, 3]数组,首先加入空集,然后循环获取数组元素,第一个元素为1,那就考虑子集为1开始的集合,除了1本身还可以组成[1, 2]或者[1, 2, 3]的子集;然后再以2开始,那这时之后获取的元素不能从下标1开始了,而是要从当前元素的下一个元素开始,不然的话会重复获取[2, 1]这种,所以又有子集[2, 3],最后后面就只有[3]了,循环结束之后就可以返回最终的所有子集了。

三、代码:

方法一

class Solution {
    public static List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        res.add(new ArrayList<Integer>());
        for (Integer num : nums) {
            int size = res.size();
            for (int i = 0; i < size; i++) {
                List<Integer> temp = new ArrayList<Integer>(res.get(i));
                temp.add(num);
                res.add(temp);
            }
        }
        return res;
    }
}

时间复杂度:O(2^^n),双重循环添加子元素。 空间复杂度:O(2^n)。

方法二

class Solution {
    List<Integer> temp = new ArrayList<Integer>();
    List<List<Integer>> res = new ArrayList<List<Integer>>();

    public List<List<Integer>> subsets(int[] nums) {
        dfs(0, nums);
        return res;
    }

    public void dfs(int cur, int[] nums) {
        if (cur == nums.length) {
            res.add(new ArrayList<Integer>(temp));
            return;
        }
        temp.add(nums[cur]);
        dfs(cur + 1, nums);
        temp.remove(temp.size() - 1);
        dfs(cur + 1, nums);
    }
}

时间复杂度:O(2^n)。 空间复杂度:O(n)。