题解
也是两题一起写。第二问的差别在于是否有重复数字。
这种求组合的,思路大体有三种:dfs,迭代,位操作。
dfs不说了很熟悉,我用位操作搞定了第一问,这里关注一下迭代。
我叙述一下迭代的过程,例如对{1,2,3},先预设返回值res为{{}}。
遍历原数组,对每个数字,依次取得现有返回值res内所有组,加上此数字,
再加回res。
第一次:
{{},{1}}
第二次:
{{},{1},{2},{1,2}}
第三次:
{{},{1},{2},{1,2},{3},{1,3},{2,3},{1,2,3}}
我不知道这叫什么做法,但是是正确的。
第二问,有重复数字的,也可按一问的思路做。
这里简要叙述一下,还是迭代的想法。第一问数是unique的,每个数只能加
一次或者零次(不加)。而第二问,所谓重复数,不过就是有点特殊,可以加 0- N(此数重复次数) 次。
Code
1
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
res.push_back(vector<int> ());
int n=nums.size();
int tmp,cur=1;
while(cur<=pow(2,n)-1){
tmp=cur;
vector<int> cot;
for(int i=0;i<n;i++){
if(tmp&1)
cot.push_back( nums[i]);
tmp>>=1;
}
res.push_back(cot);
cur++;
}
return res;
}
2
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
int n = nums.size();
sort(nums.begin(),nums.end());
vector<vector<int>> res={{}};
for(int i=0;i<n;){
int t=0;
while(t+i<n && nums[i+t]==nums[i]) t++;// t 重复次数
int k = res.size();
for(int j=0;j<k;j++){ // 迭代过程
vector<int> tmp = res[j];
for(int w=0;w<t;w++){ // 加 1 - N 次
tmp.push_back(nums[i]);
res.push_back(tmp);
}
}
i+=t;// 跳过重复数
}
return res;
}