找出一个集合的所有子集。本题目可以利用combination题目的思路,首先找出k=0的子集(空集),然后依次找出k=1, 2, 3....N的子集,N的输入集合的大小。
时间O(2^n),空间O(n)。
注意事项:
1. 因为要求每个子集的元素按升序排列,实现对输入集合先按照其元素进行排序。
2. 不要忘记空集(k=0)和全集(k=n)的情况。
代码如下:
class Solution {
public:
vector<vector<int> > subsets(vector<int> &S) {
sort(S.begin(), S.end());
vector<vector<int> > result;
vector<int> path;
for(int k=0; k<=S.size(); k++)
{
combination(k, 0, S, path, result);
}
return result;
}
void combination(int k, int start, vector<int> s, vector<int> &path, vector<vector<int> > &result)
{
if(path.size() == k)
{
result.push_back(path);
return;
}
for(int i=start; i<s.size(); i++)
{
path.push_back(s[i]);
combination(k, i+1, s, path, result);
path.pop_back();
}
}
};
方法二,不用针对每个k生成所有大小为k的子集。而是在DFS的过程中直接将当时的path加入到result中。
class Solution {
public:
vector<vector<int> > subsets(vector<int> &S) {
sort(S.begin(), S.end());
vector<vector<int> > result;
vector<int> path;
combination(0, S, path, result);
return result;
}
void combination(int start, vector<int> s, vector<int> &path, vector<vector<int> > &result)
{
result.push_back(path);
for(int i=start; i<s.size(); i++)
{
path.push_back(s[i]);
combination(i+1, s, path, result);
path.pop_back();
}
}
};
9.04 --------------------------------
Method 3: recursion. 增量构造法
class Solution {
public:
vector<vector<int> > subsets(vector<int> &S) {
const int n = S.size();
vector<vector<int> > result;
vector<int> path;
sort(S.begin(), S.end());
dfs(S, path, result, 0);
return result;
}
void dfs(vector<int> &S, vector<int> &path, vector<vector<int> > &result, int step)
{
if(step == S.size())
{
result.push_back(path);
return;
}
dfs(S, path, result, step+1);
path.push_back(S[step]);
dfs(S, path, result, step+1);
path.pop_back();
}
};
Method 4: 增量构造法,非递归
class Solution {
public:
vector<vector<int> > subsets(vector<int> &S) {
const int n = S.size();
sort(S.begin(), S.end());
vector<vector<int>> result(1);
for(int i=0; i<S.size(); i++)
{
for(int j=result.size()-1; j>=0; j--)
{
vector<int> cur(result[j].begin(), result[j].end());
cur.push_back(S[i]);
result.push_back(cur);
}
}
return result;
}
};
Method 5: 二进制法. (限制条件:集合元素个数小于int的bit数量)
class Solution {
public:
vector<vector<int> > subsets(vector<int> &S) {
const int n = S.size();
vector<vector<int> > result;
vector<int> path;
sort(S.begin(), S.end());
unsigned int power_size = pow(2, n);
for(int i=0; i<power_size; i++)
{
path.clear();
for(int j=0; j<n; j++)
{
if((i >> j)&1 == 1)
path.push_back(S[j]);
}
result.push_back(path);
}
return result;
}
};