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],
[]
]
解题思路:
方法1.回朔法。通过深度优先遍历数组,然后不断剔除已选元素,进行遍历查找:如[1,2,3,4],子集[1], 向[2,3,4]寻径 -> 最后把1剔除,选子集[2]向[3,4]寻径,以此反复c++代码如下:
void getSubset(vector<vector<int>>& res, vector<int>& sub, vector<int>nums, int i){
res.push_back(sub);
for(int j = i; j<nums.size(); j++){
// 向nums[i]寻找径
sub.push_back(nums[j]);
getSubset(res, sub, nums, j+1);
// 将num[i]剔除
sub.pop_back();
}
}
vector<vector<int>> subsets(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> res;
if(nums.empty()) return res;
vector<int> sub;
getSubset(res, sub, nums, 0);
return res;
}
方法2.循环遍历法
[]: []
[1]: [], [1]
[1, 2]: [], [1], [2], [1, 2]
[1, 2, 3]: [], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]
通过观察生成元素规律可发现,num每增加一个元素n, 其生成的subsets都是在原subset所有元素的基础上添加元素n所形成的新的子集,所以其算法可为:
vector<vector<int>> subsets(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<vector<int>> res;
if(nums.empty()) return res;
vector<int> sub;
// 一个元素都没有则res为[]
res.push_back(sub);
for(int i = 0; i < nums.size(); i++){
int n = res.size();
// 遍历原subset集合
for(int j = 0; j < n; j++){
res.push_back(res[j]);
res.back().push_back(nums[i]);
}
}
return res;
}