力扣78 子集

求数组的所有子集

比如有数组[1, 2, 3],其元素数量n = 3,将那么其子集为

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

算法(1)

使用二叉树来构建含有子集的叶子节点,然后使用中序遍历

思路

每一层代表一个元素,左子树代表不使用该节点,右子树代表使用该节点,使用中序遍历来获得全部叶子节点,那么获得该数组的子集。

在这里插入图片描述

void getArr(vector<int> List,vector<<vector>> result, vector<int> temp,int level){
    if(level == List.size()) {
        result.add(temp);
     }else{
        vector<int> temp;
        getArr(List, result, temp, level + 1);
        temp.add(List[level]);
        getArr(List, result, temp,  level + 1);   
      }
}

算法(2)

思路

因为这个可以划分出比原问题规模小却同质的问题,那么是可以用递归解决。

    vector<int> t;
    vector<vector<int>> ans;

    void dfs(int cur, vector<int>& nums){
        if(cur==nums.size()){ //到最后一位
            ans.push_back(t); //结束,返回上一层
            return;
        }
        t.push_back(nums[cur]); //取第cur+1个元素
        dfs(cur+1,nums);
        t.pop_back(); //不取第cur+1个元素
        dfs(cur+1, nums);
    }
    vector<vector<int>> subsets(vector<int>& nums) {
        dfs(0,nums);
        return ans;
    }

上面的代码中,dfs(cur,nums)参数表示当前位置是cur,原序列是nums。原序列的每个位置在答案序列中的状态有被选中和不被选中两种。

我们用t数组存放已被选出来的数字。在进入dfs(cur,nums)之前,[0,cur-1]位置的状态是确定的,而[cur, n-1] 内的位置状态是不确定的。dfs(cur,n)需要确定cur位置的状态,然后求解子问题dfs(cur+1,n)。对于cur位置,我们需要考虑a[cur]位置的状态,如果取,我们需要把a[cur]放到一个临时的答案数组中(即t数组), 再执行dfs(cur+1, n), 执行结束后需要对t进行回溯;如果不去,则直接执行dfs(cur+1, n)。在整个递归调用过程中,cur是从小到大递增的,当cur增加到n的时候,记录答案并终止递归。

时间复杂度:

二进制枚举的时间复杂度是 O(n x 2^n), 一共2^n个状态,每种状态需要O(n)的时间来构造子集。

空间复杂度:

O(n)。临时数组t的空间代价是O(n),递归时栈空间的代价为O(n)。

算法(3)

求集合的所有子集

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值