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], [] ]
思路一:输出解空间树的叶子节点,需要记录哪些是叶子节点,这就需要知道现在到底遍历到哪一层了。方法有很多,可以用全局变量记录,也可以用递归函数的参数记录。
A)这里是用全局变量记录,在进入函数的时候level++,退出函数的时候level--。
int level=0;
vector<vector<int> > result;
vector<int> temp;
void dfs(vector<int>& S){
level++;
if(level>S.size()){
result.push_back(temp);
level--;
return;
}
temp.push_back(S[level-1]);
dfs(S);
temp.pop_back();
dfs(S);
level--;
return;
}
vector<vector<int> > subsets(vector<int>& S){
sort(S.begin(),S.end());
dfs(S);
reverse(result.begin(),result.end());
return result;
}
B)这里记录层数用的是函数参数
vector<vector<int> > result;
vector<int> temp;
void dfs(vector<int>& S, int i){
if(i==S.size()){
result.push_back(temp);
return;
}
temp.push_back(S[i]);
dfs(S,i+1);
temp.pop_back();
dfs(S,i+1);
return;
}
vector<vector<int> > subsets(vector<int>& S){
dfs(S,0);
reverse(result.begin(),result.end());
return result;
}
C)上面都是用全局变量记录中间结果,其实也可以采用参数形式记录,而参数形式可以是引用传递,也可以是值传递。
这里是引用传递,类似于全局变量。
vector<vector<int> > result;
void dfs(vector<int>& S, int i, vector<int>& temp){
if(i==S.size()){
result.push_back(temp);
return;
}
temp.push_back(S[i]);
dfs(S,i+1,temp);
temp.pop_back();
dfs(S,i+1,temp);
return;
}
vector<vector<int> > subsets(vector<int>& S){
vector<int> temp;
dfs(S,0,temp);
reverse(result.begin(),result.end());
return result;
}
D) 再写一个值传递。值传递需要考虑每个参数都在栈中有一份拷贝,所以有时候不用再做运算了。
vector<vector<int> > result;
void dfs(vector<int>& S, int i, vector<int> temp){
if(i==S.size()){
result.push_back(temp);
return;
}
vector<int> v(temp);
v.push_back(S[i]);
dfs(S,i+1,v);
dfs(S,i+1,temp);
return;
}
vector<vector<int> > subsets(vector<int>& S){
vector<int> temp;
dfs(S,0,temp);
reverse(result.begin(),result.end());
return result;
}
思路二:DFS,其中关键在于空集合的处理,空集合什么时候产生??
vector<vector<int> > f(vector<int> &S, int index){
vector<vector<int> > result;
vector<int> tmp;
int n=S.size()-index;
if(n==0)
return result;
if(n==1){
result.push_back(tmp);
tmp.push_back(S[index]);
result.push_back(tmp);
return result;
}
vector<vector<int> > _result=f(S,index+1);
for(int i=0;i<_result.size();i++){
tmp.clear();
result.push_back(_result[i]);
tmp.push_back(S[index]);
tmp.insert(tmp.begin()+1,_result[i].begin(),_result[i].end());
result.push_back(tmp);
}
return result;
}
vector<vector<int> > subsets(vector<int> &S) {
sort(S.begin(),S.end());
return f(S,0);
}
这里还有个判定为错误的答案,但其实只是集合的顺序和答案不同,从数学上讲也应该是正确的答案。其中空集合产生于temp的size为1时,也就是当输入为{1}时,输出是{[],1}
vector<vector<int> > subsets(vector<int>& S) {
vector<vector<int> > result;
if(S.size()==0){
result.push_back(S);
}
while(S.size()>0){
int last=S.back();
S.pop_back();
vector<int> s(S);
vector<vector<int> > temp=subsets(s);
for(int i=0;i<temp.size();i++){
temp[i].push_back(last);
result.push_back(temp[i]);
}
if(temp.size()==1){
vector<int> a;
result.push_back(a);
}
}
return result;
}