ccpocker ccpocker‘s blog

LeetCode 78. Subset


78. Subsets

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

解法一:使用深度优先遍历dfs,分为两种:一种是递归;另一种是循环。

//使用递归进行深度优先遍历
class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res;
        vector<int> sub;
        dfs(nums,0,sub,res);
        return res;
    }
    void dfs(vector<int>& nums,int start,vector<int>& sub,vector<vector<int>>& res){
        res.push_back(sub);//推入当前子集
        for(int i=start;i<nums.size();i++){
            sub.push_back(nums[i]);
            dfs(nums,i+1,sub,res);
            sub.pop_back();
        }
    }
};

//使用循环进行深度优先遍历

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> subs(1,vector<int>());
        for(int i=0;i<nums.size();i++){
            int n=subs.size();
            for(int j=0;j<n;j++){
                subs.push_back(subs[j]);
                subs.back().push_back(nums[i]);
            }     
        }
        return subs;
    }
};

方法二:位运算方式 高中数学可知,对于一个有n个不同元素的子集共有$2^n$个子集。这是因为对于每个子集,每个元素可以出现或者不出现,故总共子集的个数为$2^n$个。

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        int n = pow(2, nums.size()); 
        vector<vector<int>> subs(n, vector<int>());
        for (int i = 0; i < nums.size(); i++) {
            for (int j = 0; j < n; j++) {
                if ((j >> i) & 1) {
                    subs[j].push_back(nums[i]);
                }
            }
        }
        return subs;
    }
};

Similar Posts

Comments