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], [] ]
题目解析:
这道题目与LeetCode | Subsets 思路一样。只是这道题目中有重复数据。
之前见过这样处理重复数据的。1、2、2、3。当遍历的时候,如果第一个2选择了,第二个2可以选择,可以不选择。如果第一个2没有选择,那么第二个2就一定不要选。同理,如果有连续三个2,只有紧挨着前一个选择了,下面的才有资格选择。
再进一步考虑的话,这也就是m个2里面选择0....m个,一共m个情况。那么我们就通过计数count来判断有多少重复数据。然后往里面添加的个数递增即可。
还有一点小技巧。对于第i个数据,我们递归过程中先选择不添加,然后选择添加,那么就不用再退出最后一个数据了。并且我们用的是tmp临时数组,传递到内部的只是一个备份,没有退出的过程。
代码如下:
#include <iostream>
#include <vector>
#include<algorithm>
using namespace std;
class Solution {
public:
vector<vector<int> > subsetsWithDup(vector<int> &S) {
vector<vector<int> >res;
vector<int> tmp;
vector<int>::size_type num;
sort(S.begin(), S.end());
GenerateSub(res,S,tmp,0);
return res;
}
void GenerateSub(vector<vector<int> >&res,vector<int> &S,vector<int> tmp,vector<int>::size_type index){
if(index >= S.size()){
res.push_back(tmp);
return ;
}
int count = 1;
for(int i = index+1;i < S.size();i++){
if(S[i] != S[index])
break;
count++;
}
GenerateSub(res,S,tmp,index+count);
for(int i = 0;i < count;i++){
tmp.push_back(S[index+i]);
GenerateSub(res,S,tmp,index+count);
}
}
};
int main()
{
vector<vector<int> >res;
Solution tp;
vector<int> S;
S.push_back(4);
S.push_back(1);
S.push_back(4);
res = tp.subsetsWithDup(S);
for(int i = 0;i < res.size();i++){
if(res[i].size() == 0){
cout << "$" << endl;
continue;
}
for(int j = 0;j < res[i].size();j++)
cout << res[i][j] << " ";
cout << endl;
}
return 0;
}