Given a set of distinct integers, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,3]
, a solution is:
[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
解法一:
这么native,通不过runtime test也正常。
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
set<vector<int>> tmp;
vector<vector<int>> res;
subsetsDFS(tmp,nums);
res.assign(tmp.begin(),tmp.end());
return res;
}
void subsetsDFS(set<vector<int>> &res, vector<int> nums){
res.insert(nums);
for(int i= 0; i<nums.size(); ++i){
vector<int> temp = nums; temp.erase(temp.begin()+i);
subsetsDFS(res, temp);
}
}
};
动态生长。先是推入一个[],遇到第一个数字,变成[] [1],遇到第二个数字,res中的每一个vector都推入2,并连同之前的结果,存在res中,以此类推。
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res(1);
for(int i=0; i<nums.size(); i++){
int len = res.size();
for(int j=0; j<len; j++){
res.push_back(res[j]);
res.back().push_back(nums[i]);
}
return res;
}
};
解法三:
将是否选择该数字进行0/1编码,比如[]对应的就是0,0,0, [1,2,3]对应的就是1,1,1。对于n个数,一共有2^n的选择。那么对0到2^n-1的每一个数,做左移,如果最低位为1,即选择对应的数字(这里使用一个index)来实现。
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
int size = pow(2,nums.size());
vector<vector<int>> res;
for(int k = 0; k<size; k++){
vector<int> out = convertIntToSet(nums,k);
res.push_back(out);
}
return res;
}
vector<int> convertIntToSet(vector<int> nums, int k){
vector<int> res;
int idx = 0;
for(int i = k; i>0; i>>=1){
if(i&1==1) res.push_back(nums[idx]);
idx++;
}
return res;
}
};