求集合子集的3中方法

1、递归

  维持一个开始位置和当前集合,每次进行加入开始位置的元素再递归、不加入就递归两种操作,代表这个元素是否出现在该集合之中

class Solution {
public:
    void subsets(vector<int>& nums, int pos, vector<int>& current, vector<vector<int>>& result){
        if(pos == nums.size()){
            result.push_back(current);
            return;
        }else{
            subsets(nums,pos+1,current,result);
            current.push_back(nums[pos]);
            subsets(nums,pos+1,current,result);
            current.pop_back();
        }
    }
    
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> result;
        vector<int> current;
        subsets(nums, 0, current, result);
        return result;
    }
};

2、迭代

  思路是从头往后遍历数组,每次遍历到一个新的成员,就将他和前面每一个集合并一下得到一连串新的集合,将这些集合加入再次做运算。

  1. Initially: [[]]
  2. Adding the first number to all the existed subsets: [[], [1]];
  3. Adding the second number to all the existed subsets: [[], [1], [2], [1, 2]];
  4. Adding the third number to all the existed subsets: [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
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;
    }
}; 

3、位图

  思路是先创建出2^n个数组,第一个元素每个2个子集出现一个,第二个隔4个、依次类推下去。用位图来判断当前集合是否该出现某个元素

  1. [], [], [], [], [], [], [], []

         2. [], [1], [], [1], [], [1], [], [1]

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

   4.[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]

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;
    }
};
原文地址:https://www.cnblogs.com/likaiming/p/9534404.html