全子集问题(subset)

全子集问题的三种解法:

1.回溯法
回溯是经典的解法,有固定的模板,用递归实现。

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> subs;
        vector<int> sub;  
        genSubsets(nums, 0, sub, subs);
        return subs; 
    }
    void genSubsets(vector<int>& nums, int start, vector<int>& sub, vector<vector<int>>& subs) {
        subs.push_back(sub);
        for (int i = start; i < nums.size(); i++) {
            sub.push_back(nums[i]);
            genSubsets(nums, i + 1, sub, subs);
            sub.pop_back();
        }
    }
};

2.迭代法
初始为空集[ ]
将上一次的解复制一遍,并往里加元素[ ][ ]→[][1]
将上一次的解复制一遍,并往里加元素[ ][1][ ][1]→[ ][1][2][1,2]
重复复制步骤[ ][1][2][1,2][ ][1][2][1,2]→[ ][1][2][1,2][3][1,3][2,3][1,2,3]

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        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;
    }
}; 

3.bit映射法
000~111共8种排列,对应着8种子集,每一bit对应着一个元素

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

【Reference】
https://leetcode.com/discuss/46668/recursive-iterative-manipulation-solutions-explanations

posted @ 2016-10-10 16:30  水煮海鲜  阅读(362)  评论(0编辑  收藏  举报