您的位置:首页 > 其它

【leetcode】subsets

2015-09-13 19:53 369 查看
题目:

Given a set of distinct integers, 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,3], a solution is:

[

[3],

[1],

[2],

[1,2,3],

[1,3],

[2,3],

[1,2],

[]

]

解答:

1.位操作

数组的子集中的数字只有两种状态 1. 存在 2. 不存在 分别用1/0来表示这两种状态,则每个子集都可以用n位的0/1的二进制数来表示

因此对于每个子集 只需要查看该子集的标号(0/1序列)各位中是否含有1,有1 表示该位的数字存在,否则 不存在,基于这个原理 可得下列的代码:

vector<vector<int> > subsets(vector<int> &S) {
//首先对原数组进行排序
sort (S.begin(), S.end());
//数组的大小 即每个子集的二进制序列的长度
int elem_num = S.size();
//子集的数目
int subset_num = pow (2, elem_num);
vector<vector<int> > subset_set (subset_num, vector<int>());
for (int i = 0; i < elem_num; i++)
for (int j = 0; j < subset_num; j++)
//判断每个子集的二进制序列的i位是否为1 为1 则存在该数(加入到子集数组中)
if ((j >> i) & 1)
subset_set[j].push_back (S[i]);
return subset_set;
}


2.

如{1,2,3}的子集 包括0个数的组合,1个数的组合,2个数的组合和3个数的组合合并而成:

vector<vector<int>> subsets(vector<int>& nums) {

res.push_back(tmp);
int n=nums.size();
if(!n) return res;

sort(nums.begin(),nums.end());
for(int i=1;i<=n;i++){
helper(nums,i,0,n-1,0);
}
return res;
}

void helper(vector<int>& nums,int k,int start,int n,int num){
if(num==k){
res.push_back(tmp);
return;
}

for(int i=start;i<=n;i++){
tmp.push_back(nums[i]);
helper(nums,k,i+1,n,num+1);
tmp.pop_back();
}
}


3. dfs(向后追溯)

vector<vector<int>> subsets(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> subs;
vector<int> sub;
genSubsets(nums, 0, sub, subs);
return subs;
}
void genSubsets(vector<int>& nums, int start, vector<int>& sub, vector<vector<int>>& subs) {

subs.push_back(sub);
for (int i = start; i < nums.size(); i++) {
//原数组的子集可由   某个数+{去掉该数的集合的子集} 得到
sub.push_back(nums[i]);
genSubsets(nums, i + 1, sub, subs);
sub.pop_back();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: