Given a list of numbers that may has duplicate numbers, return all possible subsets
Notice
- Each element in a subset must be in non-descending order.
- The ordering between two subsets is free.
- The solution set must not contain duplicate subsets.
Example
If S = [1,2,2]
, a solution is:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
Challenge
Can you do it in both recursively and iteratively?
class Solution {
private:
void subsetsWithDupHelper(const vector<int> &S, int curIdx, vector<int> &curVtr, vector<vector<int>> &retVtr, bool isPreChoosen) {
// 在前面一个数和当前的数相同的情况下
// 前选,当前可以选和不选
// 前不选, 当前不能选,只能不选
if (curIdx == S.size())
{
retVtr.push_back(curVtr);
return;
}
subsetsWithDupHelper(S, curIdx+1, curVtr, retVtr, false);
if (curIdx > 0 && S[curIdx] == S[curIdx-1] && !isPreChoosen)
return;
curVtr.push_back(S[curIdx]);
subsetsWithDupHelper(S, curIdx+1, curVtr, retVtr, true);
curVtr.pop_back();
}
public:
/**
* @param S: A set of numbers.
* @return: A list of lists. All valid subsets.
*/
vector<vector<int> > subsetsWithDup(vector<int> &S) {
// write your code here
vector<vector<int>> retVtr;
if (S.size() == 0)
return retVtr;
sort(S.begin(), S.end()); //sort是关键之一
vector<int> curVtr;
subsetsWithDupHelper(S, 0, curVtr, retVtr, true);
return retVtr;
}
};