LeetCode78--求子集

这道题目一看我,我的第一想法就是递归

    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> alllist=new ArrayList<>();
        alllist.add(new ArrayList<Integer>());
        for(int i=1;i<=nums.length;i++){
            getanswer(alllist,new ArrayList<>(),nums,i,0);
        }
        return alllist;
    }
    public void getanswer(List<List<Integer>> listall,List<Integer> list,int[] nums,int n,int start){n是子集的元素个数,start是遍历时,子集元素的下标
        if(n==0){//当n==0时,则跳出递归
            listall.add(list);
            return;
        }
        for(int i=start;i<nums.length-n+1;i++){
            ArrayList<Integer> temp=new ArrayList<>(list);//创建一个临时的list,用来保存新的结果
            temp.add(nums[i]);
            getanswer(listall,temp,nums,n-1,i+1);
        }
    }

假设数组为[1,2,3]----

先求元素个数为 1 的子集,则n等于1

则递归一次就会跳出循环。此时allList=[[1],[2],[3]];

第二次n=2
**list=[1] ,n=n-1=1—>list1=[1,2] list2=[1,3] n=n-1=0 —> alllist.add(list1) add(list2)
**list=[2] ,n=n-1=1 —>list1=[2,3] n=n-1=0 —> allllist.add(list1)
**list=[3] n=n-1=1 —>start=2, start+n=2+2=4<nums.length 结束
第三次 n=3
list=[1] n=n-1=2; -->list=[1,2] n=n-1=1;–>list[1,2,3] n=n-1=0 allList.add(list);
list=[2] i=1 i+n=4>nums.length 结束

后来看了评论区 有更好的方法

遍历一次数组,每次遍历的时候,就把之前生成的list集合复制,并添加当前遍历到值。

    public List<List<Integer>> subsets(int[] nums) {//方法二
        List<List<Integer>> alllist=new ArrayList<>();
        for(int i=0;i<nums.length;i++){
            for(int j=0,size=alllist.size();j<size;j++){
                List<Integer> copy=new ArrayList<>(alllist.get(j));
                copy.add(nums[i]);
                alllist.add(copy);
            }
            ArrayList<Integer> temp=new ArrayList<>();
            temp.add(nums[i]);
            alllist.add(temp);
        }
        alllist.add(new ArrayList<>());
        return alllist;
    }

以[1,2,3]为例
i=0 listall=[[1]]
i=1 listall=[[1],[1,2],[2]];
i=2 listall=[[1][1,2],[2],[1,3],[1,2,3][2,3],[3]]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值