LeetCode(078) Subsets (Java)

本文详细解析了如何通过深度优先搜索(DFS)算法生成给定整数数组的所有可能子集,并确保子集按非递减顺序排列且不含重复。文章提供了具体的Java实现代码,包括注意事项及常见陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目如下:

Given a set of distinct integers, nums, return all possible subsets.
Note:
Elements in a subset must be in non-descending order.
The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,3], a solution is:

  [
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
  ]

分析如下:

标准DFS题目, 所有的subset的解构成一颗树,对这棵树进行DFS遍历,把每个节点都输出即可。

我的代码:

public class Solution {
    void subsetsHelper(int[] nums, List<Integer> each,  List<List<Integer> > arrList, int start , int len) {

        // WRONG : arrList.add(each);   
        // each is only a reference, should use the new operation to instantiate a new array.

        // NOTE: something different from the normal DFS template.
        // NOTE: we need to walk throught every node of the tree, including both the leaf node and the non leaf node, hence we do not use the normal "if (star == len) {... return ;}".
        // NOTE:  if Foo is a subtype (subclass or subinterface) of Bar, and G is some generic type declaration, it is not the case that G<Foo> is a subtype of G<Bar>. This is probably the hardest thing you need to learn about generics, because it goes against our deeply held intuitions.
        // https://docs.oracle.com/javase/tutorial/extra/generics/subtype.html

        arrList.add(new ArrayList<Integer> (each)); 

        for (int i = start; i < len; ++i) { // DFS
            each.add(nums[i]);
            subsetsHelper(nums, each, arrList, i + 1, len);
            each.remove(each.size() - 1);
        } 
    };

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

        // WRONG: List<List<Integer> > result = new ArrayList<List<Integer> > ();
        // if you had a List<List<Integer>> then you'd be able to add a LinkedList<Integer> to it.
        //But you can't do this for an ArrayList<ArrayList<Integer>>, so the latter can't possibly be a type of List<List<Integer>>.

        //The reason is that generics are not covariant.
        // Consider simpler case:

        // List<Integer> integers = new ArrayList<Integer>();
        // List<Number> numbers = integers; // cannot do this
        // numbers.add(new Float(1337.44));
        // Now List holds a Float, which is certainly bad.

        // Same for your case.

        // List<ArrayList<Integer>> al = new ArrayList<ArrayList<Integer>>();
        // List<List<Integer>> ll = al; // cannot do this
        // ll.add(new LinkedList<Integer>())
        // Now you have a list ll which holds LinkedList, but the al is declared as a List of ArrayLists.

        List<List<Integer> > result = new ArrayList<List<Integer> > ();
        ArrayList<Integer> each = new ArrayList<Integer>();
        Arrays.sort(nums);
        subsetsHelper(nums, each, result, 0, nums.length);
        return result;
    }
//  public static void main(String[] args) {
//      // TODO Auto-generated method stub
//     Subsets subsets = new Subsets();
//     //int [] arr = new int []{2, 3, 1};
//     int [] arr = new int []{0};
//     List<ArrayList<Integer> > arrArr = subsets.subsets(arr);
//     System.out.println(arrArr.size());
//  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值