0
点赞
收藏
分享

微信扫一扫

LeetCode_Array_78. Subsets 求集合的所有子集 (C++)


目录

​​1,题目描述​​

​​2,思路​​

​​思路一:按位对应法​​

​​思路二:递归(回溯)​​

​​3,代码【C++】​​

​​思路一:按位对应法​​

​​思路二:递归(回溯)​​

​​4,测试效果​​

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],
  []
]


 

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()时,说明原始集合中所有元素均判断过一遍,已得出全部结果;

LeetCode_Array_78. Subsets  求集合的所有子集 (C++)_LeetCode

具体实现,请看下方代码(思路比较清晰,就不再赘述了)

  • 注意使用递归的深度,并以此作为递归出口的判断依据;
  • 回溯的两种方法:一,对每个元素标记,到底后会根据标记判断是否将此元素加入结果集;二,利用栈的特点,先入栈,后出栈,可以达到同样的效果;

 

 

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,测试不是很准确,仅供参考

思路一:

LeetCode_Array_78. Subsets  求集合的所有子集 (C++)_LeetCode_02

思路二:

我的代码:

LeetCode_Array_78. Subsets  求集合的所有子集 (C++)_C++_03

大神的代码:

LeetCode_Array_78. Subsets  求集合的所有子集 (C++)_LeetCode_04

 

举报

相关推荐

0 条评论