#78 Subsets

Description

Given an integer array nums of unique elements, return all possible subsets (the power set).

The solution set must not contain duplicate subsets. Return the solution in any order.

Examples

Example 1:

Input: nums = [1,2,3]
Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]

Example 2:

Input: nums = [0]
Output: [[],[0]]

Constraints:

1 <= nums.length <= 10
-10 <= nums[i] <= 10
All the numbers of nums are unique.

解题思路1及对应代码

这个解题思路的出现是因为不想通过迭代的方式,想直接通过循环解决对应问题,当然效果会很差(时间复杂度&空间复杂度双高),但也是一种解法。

复杂原因主要在于每次都要进行排序(本来以为HashSet可以自动完成排序,但其实HashSet并不能确保有序),所以还要耗费时间做一次sort,再加上每次都要用set进行list去重,虽然最后只用处理1/2的数据,但总体的步骤还是比迭代来的耗时。

可以注意一下int数组转List<Integer>的方法

代码1

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> answer = new ArrayList<>();
        List<Integer> one = Arrays.stream(nums).boxed().collect(Collectors.toList());
        int len = nums.length;
        List<List<Integer>> addition = new ArrayList<>();
        addition.add(new ArrayList<>());
        answer.add(new ArrayList<>());
        answer.add(new ArrayList<>(one));
        
        for(int i = 0; i < len / 2; i = i + 1){
            List<List<Integer>> temp = new ArrayList<>();
            for(List<Integer> add: addition){
                for(Integer num: nums){
                    List<Integer> li = new ArrayList<>(add);
                    int pre_len = li.size();
                    li.add(num);
                    li = new ArrayList<>(new HashSet<>(li));
                    int aft_len = li.size();
                    if (pre_len != aft_len){
                        Collections.sort(li);
                        temp.add(li);
                    }
                }
            }
            temp = new ArrayList<>(new HashSet<>(temp));
            addition = new ArrayList<>(temp);
            answer.addAll(temp);
            
            if (i == len / 2 - 1 && len % 2 == 0){
                break;
            }
            
            temp = new ArrayList<>();
            for (List<Integer> add: addition){
                List<Integer> fullSet = new ArrayList<>(one);
                fullSet.removeAll(add);
                temp.add(fullSet);
            }
            answer.addAll(temp);
        }
        return answer;
    }
}

解题思路2及对应代码

这一个版本就是很常规的迭代思想,以[1, 2, 3]为例
答案的更迭变化为
[]
[] [1] (在上一轮的基础上+1)
[] [1] [2] [1, 2] (在上一轮的基础上+2)
[] [1] [2] [1, 2] [3] [1, 3] [2, 3] [1, 2, 3] (在上一轮的基础上+3)

需要注意的是,用

List<List<Integer>> ls2 = new ArrayList<>(ls1)

并不能完成硬拷贝!(得用循环或者用stream)

代码2

class Solution {
    public List<List<Integer>> process(int add, List<List<Integer>> tempAnswer){
        List<List<Integer>> answer = new ArrayList<>();
        for(List<Integer> ans: tempAnswer){
            List<Integer> newAns = new ArrayList<>(ans);
            newAns.add(add);
            answer.add(newAns);
        }
        return answer;
    }
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> answer = new ArrayList<>();
        answer.add(new ArrayList<>());
        for(int num: nums){
            List<List<Integer>> tempAnswer = process(num, answer);
            answer.addAll(new ArrayList<>(tempAnswer));
        }
        return answer;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值