1. 背
这道题好绕啊。一般而言去重有两种办法,我常用的就是哈希,如果能排序可能会更好。
这道题两种办法应该都行,因为本来就有空间复杂度,再加一个哈希没区别。因为输出不要顺序,随意排序也行。
就说排序的,因为哈希的方法是一样的。先对所有数据进行排序。有一种情况比较特殊:如果当前这个数和上一个数一样,而且这个数字之前就出现过,但是我当时没用,那么这次也别用了,机不可失时不再来。怎么判断之前是否有机会选呢?用num[index-1]==num[index]来判断之前是否有机会选这个点。
那怎么看
到一个地点有两种选择:选这个点和不选这个点。
选这个点是没有限制的,因为1,2选完了,1,2,2还是可以继续选的。不过不选是可能有重复的,要看之前是否选择过,如果有机会选却没用,就说明一定有另一种情况选了带那个带的,因此就不要选了。
2. 题目
- 子集 II
给你一个整数数组 nums ,其中可能包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
示例 1:
输入:nums = [1,2,2]
输出:[[],[1],[1,2],[1,2,2],[2],[2,2]]
示例 2:
输入:nums = [0]
输出:[[],[0]]
3. 答案
class Solution {
public:
vector<int>num;
int n;
vector<vector<int> >ret;
void subset_cur(bool hasUsedLast, vector<int>&cur, int index)
{
if(index>=n)
{
ret.push_back(cur);
return;
}
subset_cur(false, cur,index+1);
if(index>0 && num[index-1]==num[index] && !hasUsedLast)///<可以加,上次没加就拉倒吧,机会过了就没了
return;
cur.push_back(num[index]);
subset_cur(true, cur,index+1);
cur.pop_back();
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<int>cur;
n = static_cast<int>(nums.size());
num = nums;
subset_cur(false, cur, 0);
return ret;
}
};