您现在的位置是:首页 >技术交流 >LeetCode ! 78. subsets网站首页技术交流

LeetCode ! 78. subsets

萝卜丝皮尔 2024-08-08 00:01:02
简介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; 
    }
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。