目录
1,题目描述
Given a set of distinct integers, nums, return all possible subsets (the power set).
Note: The solution set must not contain duplicate subsets.
Example:
Input: nums = [1,2,3]
Output:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subsets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2,思路
参考这位大神的文章@犀牛饲养员 【求一个集合的所有子集问题】
先鼓掌,后欣赏。hhhhhh
思路一:按位对应法
思路十分简单直接。
以{1,2,3}为例;
000-111分别对应{}-{1,2,3},0表示无,1表示有;
这样只需要将mark从000-111递增,每递增一次判断mark的所有位(二进制),若为1,则将nums中的对应位添加入temp中;
需要注意区分二进制与十进制的关系!
思路二:递归(回溯)
以{1,2,3}为例
这张图讲的很清楚了;
初始时为空集,判断是否将1添加入集合中,到达第一层;
再判断是否将2添加入集合中,到达第二层;
......
深度到达nums.size()时,说明原始集合中所有元素均判断过一遍,已得出全部结果;
具体实现,请看下方代码(思路比较清晰,就不再赘述了)
- 注意使用递归的深度,并以此作为递归出口的判断依据;
- 回溯的两种方法:一,对每个元素标记,到底后会根据标记判断是否将此元素加入结果集;二,利用栈的特点,先入栈,后出栈,可以达到同样的效果;
3,代码【C++】
思路一:按位对应法
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> ans;
int end = (1 << nums.size()) - 1; //例如1<<3=8(1000),7-1=6(111),正好与000-111对应
vector<int> temp = {}; //临时的容器
for(int mark = 0 ; mark <= end ; mark++){
//此处为按位与 &,将每一位与mark进行测试 得出哪一位为1 就将其添加入temp
for(int i = 0 ; i < nums.size() ; i++){
if((mark & (1 << i)) != 0) temp.push_back(nums[i]); //注意优先级!
}
ans.push_back(temp);
temp = {}; //记得清空!
}
return ans;
}
};
思路二:递归(回溯)
我的代码:
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> ans;
vector<bool> tag(nums.size(),false); //判断哪个元素存在
getSubsets(nums, tag, 0, ans);
return ans;
}
void getSubsets(vector<int> nums, vector<bool> tag, int depth, vector<vector<int>>& ans){
//原始集合中所有元素均遍历一遍
if(depth == nums.size()){
vector<int> temp;
for(int i = 0 ; i < tag.size() ; i++){
if(tag[i] == true) temp.push_back(nums[i]);
}
ans.push_back(temp);
}
else{
tag[depth] = true;
getSubsets(nums, tag, depth+1, ans);
tag[depth] = false;
getSubsets(nums, tag, depth+1, ans);
}
}
};
大神的代码:
class Solution {
public:
vector<vector<int>> ans;
vector<int> tmp;
void find(int dep, vector<int>& nums)
{
if(dep <= 0)
{
ans.push_back(tmp);
return;
}
tmp.push_back(nums[dep - 1]);
find(dep - 1, nums);
tmp.pop_back();
find(dep - 1, nums);
}
vector<vector<int>> subsets(vector<int>& nums) {
find(nums.size(), nums);
return ans;
}
};
这就是差距。。。
4,测试效果
emmm,测试不是很准确,仅供参考
思路一:
思路二:
我的代码:
大神的代码: