题目:
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], [] ]题意解析:
这道题目是让我们输出一个集合所有的子集,包括空集和它本身。可采用如下的算法来实现:
令输入nums = 【1,2,2】,用vector<vector<int> > res来存储结果。
按顺序遍历整个集合:
第一步res为空,将{1}加入res中,现在res中有{{1}}
第二步,复制res中所有的集合,此时res = { {1} ,{1}},将新元素2加入到所复制的新集合中,此时res = { {1},{1,2}},再将新元素2自己作为一个子集加入到res中,第二步结束后,res变为 { {1},{1,2},{2}}
第三步,重复第二步的操作,复制res中所有的集合,此时res变为{ {1},{1,2},{2},{1},{1,2},{2} },将新元素2加入其中新复制的集合,注意这里要检查重复,在子集{1}中加入2得到{1,2}和已有的子集{1,2}重复,故这时要舍弃该复制的结合,第三步结束后,res = {{1},{1,2},{2},{1,2,2},{2,2}}
第四步,nums已遍历完毕,加入空集即可得到答案。
一种c++的实现方式如下:
#include<iostream> #include<vector> using namespace std; class Solution { public: vector<vector<int> > subsetsWithDup(vector<int>& nums) { vector<vector<int> > res; int n = nums.size(); int res_num = 0; for(int i = 0; i < nums.size(); i++) { //new_count用来记录有多少个成功的合被复制 int new_count = 0; for(int j = 0; j < res_num; j++) { vector<int> temp; copy(temp,res[j]); temp.push_back(nums[i]); if(!is_dup(res,temp)) { res.push_back(temp); new_count++; } } //用来记录复制次数 res_num = res_num + new_count; vector<int> temp; temp.push_back(nums[i]); if(!is_dup(res,temp)) { res.push_back(temp); res_num = res_num+1; } } vector<int> temp; res.push_back(temp); return res; } void print(vector<int> v) { for(int i = 0; i < v.size(); i++) { cout<<v[i]<<" "; } cout<<endl; } //集合复制 void copy(vector<int> &v1, vector<int> &v2) { for(int i = 0; i < v2.size(); i++) { v1.push_back(v2[i]); } } //检查集合重复,就是判断两个集合是否相等 bool is_dup(vector<vector<int> > v1, vector<int> v2) { sort(v2.begin(),v2.end()); for(int i = 0; i < v1.size(); i++) { sort(v1[i].begin(),v1[i].end()); if(v1[i] == v2) return true; } return false; } };