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.第一个选或者不选、第二个选或者不选、....
void Dfs(S, index, item) {
if(index == S.size()) {
ret += item;
}
Dfs(S, index+1, item);
item.push_back(S[index]);
Dfs(S, index+1, item);
}
2.用二进制位表示选或者不选,0~2^n - 1。例如n = 3
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
考虑用位来存储信息。
for(i = 0; i < pow(2, n); i++) {
item.clear();
for(bit = 0; bit < n; bit++) {
exist = (i >> bit) & 1;
if(exist) item.push_back(s[bit]);
}
ret += item;
}
3.dp来解决,dp[i] 表示i到N的所有子集,根据dp[i +1] 可以求出dp[i],其中边界为dp[len - 1]。有与只需要最后结果,可以用sets来存储dp数据
len = s.size();
sets[len - 1] = {空 + s[len - 1]};
for(i = len - 1; i >= 0; i--) {
for(j = 0; j < sets.size(0; j++) {
tmp = sets.size();
tmp += s[i];
sets += tmp;
}
}
方法四:以{1、2、3}为例,根据 空子集 + {1...、 2...、 3... }来构建树,每一次函数调用访问树的所有子节点。
ret += path; //空子集
DFS(s, start, path) {
for(i = start; i < s.size(); i++) {
path += s[i];
ret += path;
DFS(s, i+1; path);
path -= s[i];
}
}