题目
Given a collection of integers that might contain duplicates, S, return all possible subsets.
Note:
- Elements in a subset must be in non-descending order.
- The solution set must not contain duplicate subsets.
For example,
If S = [1,2,2]
, a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
同之前的求全部组合相似,不过这次元素有重复。
可以用相同的思路进行,每次递归压入一个元素,但是要保证压入的元素和上次弹出的元素不同。
代码:
class Solution {
vector<vector<int>> ans; //结果
vector<int> com; //一个组合
int last_end; //上一次弹出的数
public:
void inner_comb(vector<int> &s,int n,int k)
{
if(com.size()==n) //获得组合,压入
ans.push_back(com);
else if(k>=s.size()) //剩下的元素不够,放弃
return;
else //正常递归
{
int len=s.size()-n+com.size(); //长度
for(int i=k;i<=len;i++)
{
if(s[i]!=last_end) //当前元素不等于上次弹出的元素
{
com.push_back(s[i]);
inner_comb(s,n,i+1); //递归
last_end=com.back(); //更新上次弹出的元素
com.pop_back();
}
}
}
}
void comb(vector<int> &s,int n) //求s中长度为n的所有组合
{
com.clear();
last_end=0xfffffff;
if(n<=0||s.empty()||n>s.size()) //空时压入空组合
{
ans.push_back(com);
return;
}
inner_comb(s,n,0); //递归求解
}
vector<vector<int> > subsetsWithDup(vector<int> &S) {
ans.clear();
sort(S.begin(),S.end()); //排序
for(int i=0;i<=S.size();i++) //求各个长度的组合
comb(S,i);
return ans;
}
};