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], [] ]
题意:可能有重复的元素,返回所有子集。
思路:这题是subsets的扩展。大致的思路也是相同的,先是对给定整数进行排序,这样就可以保证所求的子集都是非降序的;在循环或递归的过程中跳过重复的。DFS法的代码如下:
1 class Solution { 2 public: 3 vector<vector<int> > subsets(vector<int> &S) 4 { 5 vector<vector<int>> res; 6 vector<int> midArray; 7 sort(S.begin(),S.end()); 8 getSubsets(S,0,midArray,res); 9 10 return res; 11 } 12 13 void getSubsets(vector<int> &S,int beg,vector<int> &midArray,vector<vector<int>> &res) 14 { 15 res.push_back(midArray); 16 for(int i=beg;i<S.size();++i) 17 { 18 midArray.push_back(S[i]); 19 getSubsets(S,i+1,midArray,res); 20 midArray.pop_back(); 21 22 while(S[i]==S[i+1]) //跳过重复的元素 23 i++; 24 } 25 } 26 };
迭代法:代码来源Grandyang的博客。其主要思路是,定义变量last记录下有重复的开始,因为第一个重复的元素,已经和之前res中的区间形成新的一部分,第二或其以后的重复元素,只要和新形成的部分结合就好,因为之前的已经结合过了。代码如下:
1 class Solution { 2 public: 3 vector<vector<int> > subsets(vector<int> &S) 4 { 5 vector<vector<int>> res(1); 6 if(S.size()==0) return res; 7 8 sort(S.begin(),S.end()); 9 int size=res.size(); 10 if(S.size()==0) return res; 11 int last=S[0]; 12 13 for(int i=0;i<S.size();++i) 14 { 15 if(last !=S[i]) 16 { 17 last=S[i]; 18 size=res.size(); 19 } 20 21 int newSize=res.size(); 22 for(int j=newSize-size;j<newSize;++j) 23 { 24 res.push_back(res[j]); 25 res.back().push_back(S[i]); 26 } 27 } 28 return res; 29 } 30 };