题目:
Given a collection of integers that might contain duplicates, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,2]
, a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
思路:
求子集的问题一般套路都是:1)排序;2)深度优先搜索。在第k个节点,我们有两种选择:a是取nums[k],b是不取nums[k]。如果nums中有重复元素就需要小心了:假设nums[i]到nums[j] (i < j)都相等,那么为了避免生成重复子集,在处理nums[i]时,如果选择了nums[i]并且回溯完成,那么就不用再从nums[i+1]到nums[j]之间继续回溯了,这是因为从nums[i+1]到nums[j]之间的元素回溯可能生成的结果都已经在nums[i]的回溯过程中产生了,不会产生遗漏。
代码:
class Solution {
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
if (nums.size() == 0) {
return {};
}
vector<vector<int>> result;
sort(nums.begin(), nums.end());
DFS(nums, result, vector<int>(), 0);
return result;
}
private:
void DFS(const vector<int>& nums, vector<vector<int>> &result, vector<int> vec, int k) {
if (k >= nums.size()) {
return result.push_back(vec);
}
int x = k;
while (k + 1 < nums.size() && nums[k] == nums[k + 1]) {
k++; // avoid duplicates
}
DFS(nums, result, vec, k + 1); // without nums[x]
vec.push_back(nums[x]);
DFS(nums, result, vec, x + 1); // with nums[x]
}
};