Given a set of distinct integers, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example,
If nums = [1,2,3], a solution is:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
递归回溯问题详见39. Combination Sum。本题的重点在于抽象递归子过程,从[1,2,3]中组成子集可以考虑子集的个数是0个还是3个,递归子过程可以定义为从集合nums[start .. nums.size() - 1]中选出n个数构成一个子集,其中start表示从那个数开始考虑。
解题代码
// 求不具重复元素集合的子集
class Solution {
private:
vector<vector<int>> res;
// 从集合nums[start .. nums.size() - 1]中选出n个数组成子集,c中已存放前面的结果
void generateSubnetsByN(vector<int>& nums, int start, int n, vector<int> &c){
// 递归终止
if (n == 0){
res.push_back(c);
return;
}
// 递归过程
for (int i = start; i < nums.size(); i++){
c.push_back(nums[i]);
// 递归,下一次递归即使从[i + 1,nums.size() - 1]中选出n-1个数组成子集
generateSubnetsByN(nums, i + 1, n - 1, c);
c.pop_back(); //回溯过程
}
}
public:
vector<vector<int>> subsets(vector<int>& nums) {
// 初始
res.clear();
// 边界
if (nums.empty())return res;
// 用于存放中间过程,即是子集集合
vector<int> c;
for (vector<int>::size_type i = 0; i <= nums.size(); i++){
generateSubnetsByN(nums, 0, i, c);
}
return res;
}
};
测试
class TestHelper{
Solution s;
public:
void run(){
int candiate[] = { 1,2,3 };
vector<int> vec(candiate, candiate + 3);
Utils::showVecInfo(vec);
vector<vector<int>> res = s.subsets(vec);
// 显示结果信息
Utils::showVecInfo(res);
}
};
结果
vector : [ 1 2 3 ]
vector<vector<int>> :
[
[ ]
[ 1 ]
[ 2 ]
[ 3 ]
[ 1 2 ]
[ 1 3 ]
[ 2 3 ]
[ 1 2 3 ]
]
请按任意键继续. . .