LeetCode - 78. 子集(迭代、递归、回溯)

  1. 子集

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

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

示例:

输入: nums = [1,2,3]

输出:

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

题目:

方法一: 递归

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        if (nums == null) return res;
        helper(res,nums,new ArrayList<Integer>(),0);
        return res;
    }

    private void helper(List<List<Integer>> res, int[] nums, ArrayList<Integer> list, int index) {
        //终止条件
        if (index == nums.length){
            res.add(new ArrayList<Integer>(list));
            return;
        }
//        下到下一层
        helper(res,nums,list,index+1);      //list存储的是中间结果
        list.add(nums[index]);
        helper(res,nums,list,index+1);
        //释放资源
        list.remove(list.size()-1);
    }
}

方法二: 迭代
在这里插入图片描述
先加入一个空集让他成为新的子集,然后每遍历一个元素就在原来的子集的后面追加这个值

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

    public List<List<Integer>> subsets(int[] nums){
        int n= nums.length;
        for (int mask = 0; mask < (1 << n); mask++) {
            t.clear();
            for (int i = 0; i < n; i++) {
                if ((mask & (1<<n)) != 0){
                    t.add(nums[i]);
                }
            }
            ans.add(new ArrayList<Integer>(t));
        }
        return ans;
    }
public List<List<Integer>> subsets(int[] nums) {
    List<List<Integer>> res = new ArrayList<>(1 << nums.length);
    //先添加一个空的集合
    res.add(new ArrayList<>());
    for (int num : nums) {
        //每遍历一个元素就在之前子集中的每个集合追加这个元素,让他变成新的子集
        for (int i = 0, j = res.size(); i < j; i++) {
            //遍历之前的子集,重新封装成一个新的子集
            List<Integer> list = new ArrayList<>(res.get(i));
            //然后在新的子集后面追加这个元素
            list.add(num);
            //把这个新的子集添加到集合中
            res.add(list);
        }
    }
    return res;
}

类似题目:

这类题目都是同一类型的,用回溯算法 !
其实回溯算法关键在于:不合适就退回上一步
然后通过约束条件, 减少时间复杂度.

回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

  1. 组合总和

  2. 组合总和 II

  3. 全排列

  4. 全排列 II

  5. 子集

  6. 子集 II

posted @ 2020-10-31 17:00  your_棒棒糖  阅读(47)  评论(0编辑  收藏  举报