题目描述:
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).
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], [] ]
解题思路:
解题思路和Subsets的差不多,不过这次因为有了重复数,不能直接在n-1个元素的所有子集上直接加上第n个元素直接得到n个元素了。
不过通过观察可以知道:若直接按上述的方法做,n个元素的子集重复的部分是n-2个元素的所有子集加上第n-1元素:
//n=1 [ [], [1] ] ↓ //n=2 [ [], [1], [2], [1,2] ] ↓ //n=3 [ [], [1], [2], [1,2], [2], [1,2], [2,2], [1,2,2] ]
可知重复的部分[2],[1,2]是n=1的元素的所有子集加上n=3的元素,所以在添加的时候要加入一个判断语句,如果现在的元素等于上一个元素,那么就略过上次添加过的子集,也就是从上上个元素的子集之后开始添加。
代码:
1 class Solution { 2 public: 3 vector<vector<int>> subsetsWithDup(vector<int>& nums) { 4 vector<vector<int>> ret(1);//先输入一个空集 5 int n = nums.size(), pre_s = 1, cur_s = 0; 6 if(n == 0) 7 return ret; 8 sort(nums.begin(),nums.end());//排序 9 vector<int> t = {nums[0]};//输入第一个元素,ret中现在是第一个元素的所有子集 10 ret.push_back(t); 11 for(int i = 1; i < n; i++){ 12 //从第二个元素开始遍历添加 13 cur_s = ret.size();//上一个元素的子集个数 14 int j = nums[i] != nums[i-1]?0:pre_s;//判断是否相等 15 while(j < cur_s){ 16 vector<int> t(ret[j++]); 17 t.push_back(nums[i]); 18 ret.push_back(t); 19 } 20 pre_s = cur_s;//上上个元素的子集个数 21 } 22 return ret; 23 } 24 };