本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
Subsets
Total Accepted: 12378 Total Submissions: 45331Given 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:dfs暴力枚举
每一个元素,都有两种选择,选或不选,如下所示
元素1
选/ \不选
元素2
选/ \不选
用dfs遍历这棵树,记录下路径
当遍历到叶子节点的时候,就把路径添加到结果中去
实现:
用递归实现。
void subsets(vector<int> S, vector<int> path, int step, vector<vector<int> >result)
表示前面部分的路径是path,将S从step开始的后半部分的所有可能子集和前面的path组合起来一个子集加入到result中
注:在用递归实现的时候要清楚在知道你那个递归函数表示的是什么意思
复杂度:时间,O(2^n);空间,O(n)
<pre name="code" class="cpp">class Solution {
public:
vector<vector<int> > subsets(vector<int> S){
sort(S.begin(),S.end());
vector<vector<int> > result;
vector<int> path;
subsets(S, path, 0, result);
return result;
}
void subsets(vector<int> S, vector<int> path, int step, vector<vector<int> > &result){
if(step == S.size()){
result.push_back(path);
return;
}
subsets(S, path, step + 1, result);//不选择第step个元素
path.push_back(S[step]); //选择第step个元素
subsets(S, path, step + 1, result);
//path.pop_back(); //别人的代码有这一步,我觉得不用。因为按照我这个递归函数的定义,前面已经选与不选然后递归执行subsets已经生成了所有的result,后面这一步没意义。
//--> 如果把 参数 path 改为引用是需要 path.pop_back();这一步的,实际上就应该是引用,引用能节省空间。
}
};