【每日刷题】子集

版权声明:本文为博主原创文章,未经博主允许不得转载。 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却依旧很慢。
image.png-20.3kB

方法二:不采用递归的方式,而是采用 位运算 的方式。
例如: 数组 [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;
    }

运行结果:image.png-19.1kB


我的微信公众号在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sd4567855/article/details/87211483