LeetCode ! 78. subsets

参考资料:leetcode评论区,左程云算法课

78. Subsets
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.

 

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]]

思路1:使用递归函数做深度优先遍历;

注意:List , ArrayList, LinkedList的一些增删函数。
这里 我们借用 LinkedList 型的path 来收集 一个集合中该容纳的元素,因为如此一来,我们可以很方便地从链表的尾部加入和删除数据。

public List<List<Integer>> subsets(int[] nums){

        List<List<Integer>> ans = new ArrayList<>();

        LinkedList<Integer> path = new LinkedList<>();
        f(nums,0,path,ans);
        return ans;
    }
    public void f(int[] nums, int i,  LinkedList<Integer> path, List<List<Integer>> ans)
    {
        if(i==nums.length)
        {                
            ans.add(copy(path));
            return;
        }

        f(nums,i+1,path,ans);

        path.addLast(nums[i]);
        f(nums,i+1,path,ans);
        path.pollLast();
    }
    
    public List<Integer> copy(LinkedList<Integer> path)
    {
        List<Integer> ans = new ArrayList<>();
        for(Integer i:path)
        {
            ans.add(i);
        }
        return ans; 
    }

思路2:使用二进制(来自LeetCode官方题解)

一个长度为n的数组,它所有的子集数是2^n。
可以考虑使用n个二进制位组成的数代表一个集合,具体地,如果第i个二进制位上是1,那么 把nums[i]纳入到集合中;如果第i个二进制位上是0,那么 不把nums[i]纳入到集合中。
例如: nums = [3,56,24],
“001” ---- > {24}.

 public List<List<Integer>> subsets(int[] nums){

        List<List<Integer>> ans = new ArrayList<>();

        List<Integer> path = new ArrayList<>();

        int n = nums.length;

        for(int mask=0;mask<(1<<n);mask++)
        {
            path.clear();
            for(int i=0;i<n;i++)
            {
               if((mask&(1<<i))!=0)
               {
                   path.add(nums[i]);
               }
            }
            ans.add(new ArrayList(path));// !! 注意这里要新建并拷贝过去,不是直接add. 防止后续的操作对“表面上已经收入ans中的答案”产生干扰
        }

          return ans; 
    }

思路3:逐步增长(来自LeetCode评论区大佬)

思想是:先在ans中生成一个空集合,新来一个数,则把已有的所有集合都加上这个数,形成新集合。再把这些新集合加入到ans中,这样随着数组的遍历,逐步增长出来所有子集合。

  public List<List<Integer>> subsets(int[] nums){

        List<List<Integer>> ans = new ArrayList<>();

        List<Integer> path = new ArrayList<>();

        int n = nums.length;

        ans.add(new ArrayList<>());
        for(int i:nums)
        {
            int size=ans.size();
            for(int j=0;j<size;j++)
            {
               List<Integer> list  = new ArrayList<>(ans.get(j));
                list.add(i);
                ans.add(list);
            }
        }
          return ans; 
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值