letcode 子集

题目描述:
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
思路:此题属于动态规划问题,比如给一个数组[1,2,3],然后找出它的所有子集,刚开始我是想先从大向小化,也就是把1,2,3化成12,13,23,然后就是1,2,1,3,2,3,这样就出现了重复,所有要从小向大化,先使用一个集合来保存单个的,即1,2,3。然后遍历这个集合,先遍历1,从数组中找1之后的数,和1放一起加入新数组,新数组为12,13,依次类推即可.
代码实现:

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        List<Integer> tt = new ArrayList<Integer>();
        result.add(tt);
        if(nums.length==0||nums==null) return result;
        int n = nums.length;
        //第一次循环,集合中保存数的长度为1
        for(int i=0;i<n;i++) {
            List<Integer> temp = new ArrayList<Integer>();
            temp.add(nums[i]);
            result.add(temp);
        }
        //len为当前的数组长度
        int len = result.size();
        //start为当前要遍历的第一个集合,因为我先加的是空集合,所有从下标为1开始遍历
        int start=1;
        while(start<len-1) {
            List<Integer> temp = result.get(start);
            int ttt = temp.size();
            int vvv = temp.get(ttt-1);
            int h=0;
            //判断是否还用继续遍历
            boolean f = false;
            //找到第一个要添加进去的数组下标
            while(nums[h]!=vvv) h++;
            //利用前一个数组来生成新数组
            for(int i=h+1;i<nums.length;i++) {
                ArrayList<Integer> v = new ArrayList<Integer>();
                f= true;
                v.addAll(temp);
                v.add(nums[i]);
                result.add(v);
            }
            //集合遍历完后改变len和start
            if(start==len-2) {
                //len变为新的长度
                int newlen = result.size();
                //start变为下次要遍历的那个下标
                start = len-1;
                len = newlen;

            }
            start++;

        }
        return result;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37520037/article/details/82701610