由于78题和90题都属于同一类问题,在此一致解决,使用的方法都是一种回溯递归的方法,具体题目如下:
找到这个数组所有子集。思路是分别产生0- nums.size()的子集,再将其合并即可,对于每一个元素,可以选择或者不选择,当选择长度达到指定长度以后即压入一个答案,具体如下:
class Solution {
public:
void comb(vector<int>list,int s, int e,int m,vector<vector<int>>&result,vector<int>&condition)
{
int i;
if (s > e)
return;
if (condition.size() == m)
{
result.push_back(condition);
return;
}
condition.push_back(list[s]);
comb(list,s + 1, e, m,result,condition);
condition.pop_back();
comb(list,s + 1, e, m,result,condition);
}
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> ans;
for(int i=0;i<=nums.size();i++)
{
vector<vector<int>> tmp;
vector<int>condition;
comb(nums,0,(int)nums.size(),i,tmp,condition);
ans.insert(ans.end(),tmp.begin(),tmp.end());
}
return ans;
}
};
最终运行只需要4ms,打败100%(虽然后来几次跑时间有波动。。。。),不过条理还是比较清晰的,并且一般的这种类型的题目都可以利用这种回溯的方法解决。比如90题
需要针对包含相同元素的数组进行子集生成,利用以上代码运行的话,就会存在冗余答案(比如[1,2]会进入两次),因此只需要在加入答案前将condition排序,最后结果返回时利用set过滤元素即可。
class Solution {
public:
void comb(vector<int>&nums,int s,int e,int len,vector<vector<int>>&res,vector<int>&condition)
{
if(s>e) return;
if(condition.size()==len)
{
vector<int>sorted(condition);
sort(sorted.begin(),sorted.end());
res.push_back(sorted);
return;
}
condition.push_back(nums[s]);
comb(nums,s+1,e,len,res,condition);
condition.pop_back();
comb(nums,s+1,e,len,res,condition);
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
vector<vector<int>> ans;
for(int i=0;i<=nums.size();++i)
{
vector<vector<int>> tmp;
vector<int> condition;
comb(nums,0,(int)nums.size(),i,tmp,condition);
ans.insert(ans.end(),tmp.begin(),tmp.end());
}
set<vector<int>> st(ans.begin(),ans.end());
ans.assign(st.begin(),st.end());
return ans;
}
};