版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sd4567855/article/details/87211483
day34 子集
题目来源:leetcode
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
3,
1,
2,
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
解法: 提供两种方法。其方法的本质都是:对于每一个元素,均存在两种状态,即 在该子集中/不在该子集中, 逐一进行枚举即可。
方法一:dfs(秒天秒地秒一切)
vector<vector<int>> res;
vector<vector<int>> subsets(vector<int>& nums) {
dfs(0, {}, nums);
return res;
}
void dfs( int i, vector<int> temp, vector<int>& nums){
if( i == nums.size()){
res.push_back( temp);
return;
}
temp.push_back( nums[i]);
dfs( i + 1, temp, nums);
temp.pop_back();
dfs( i + 1, temp, nums);
}
运行结果:即使20ms却依旧很慢。
方法二:不采用递归的方式,而是采用 位运算 的方式。
例如: 数组 [1,2,3]的子集也就是其中的三个元素取与不取的组合。把它想象为二进制的三个 bit 位 1 1 1,那么从 0 0 0 到 1 1 1 的 8 个数,就构成了所有子集的选取情况。比如 0 0 1 表示取第1个元素,0 1 1 表示取前两个元素。
代码:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>> res;
vector<int> record, rec;
for( int i = 0; i < pow( 2, nums.size()); i++){
int temp = i;
while( temp){
record.push_back( temp % 2);
temp/=2;
}
for( int j = 0; j < record.size(); j++)
if( record[j])
rec.push_back( nums[j]);
res.push_back( rec);
record.clear(), rec.clear();
}
return res;
}
运行结果: