78 子集

78 子集

解法一.位运算

对于一个大小为m的数组,他共有2m种组合,也就是有2m个子集

例如 nums = [1,2,3]

那么他的子集则为

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

而我们知道任何一个整数的二进制表示是唯一的,所以我们可以利用这个特性解决这道题

例如 nums的大小为3,所以易知nums会有 2^3 =8个子集,我们分别写出0-7的二进制表示

0    000     []
1    001     [1]
2    010     [2]
3    011     [2,1]
4    100     [3]
5    101     [3,1]
6    110     [3,2]
7    111     [3,2,1]

观察可以得出当这些二进制中的每一位分别代表数组中的一个元素时,每个数字就分别表示了其中一个子集,而这8个则完整的构成所有子集

代码如下


class Solution {
public:
    vector<vector<int>> subsets(vector<int> &nums) {
        vector<vector<int>> res;
        int n = nums.size();
        cout << (1 << n) << endl;
        for (int i = 0; i < (1 << n); i++) {
            vector<int> temp;
            for (int j = 0; j < n; j++) {
                cout << (i >> j) << "  " << ((i >> j) & 1) << endl;
                if (i >> j & 1)
                    temp.push_back(nums[j]);
            }
            res.push_back(temp);
        }
        return res;
    }
};

解法二.回溯

class Solution {
public:
    vector<vector<int>> save;

    void set(int i, const vector<int> &num, int val, vector<int> vec) {
        vec.push_back(val);
        save.push_back(vec);
        if (i == num.size())
            return;
        for (int x = i; x < num.size(); ++x)
            set(x + 1, num, num[x], vec);
    }

    vector<vector<int>> subsets(vector<int> &nums) {
        if (nums.empty())
            return save;
        for (int x = 0; x < nums.size(); ++x)
            set(x + 1, nums, nums[x], {});
        save.push_back({});
        return save;
    }
};
原文地址:https://www.cnblogs.com/INnoVationv2/p/10276857.html