日常刷题 leetcode 78. Subsets

Given a set of distinct integers, nums, return all possible subsets (the power set).
Example:

Input: nums = [1,2,3]
Output:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
Note: The solution set must not contain duplicate subsets.
每一道题都不只有一种解法,首先抛砖引玉,写出自己浅薄的解法,然后再列出leetcode标准答案里更好的解法。
自己的解法
分析题意,脑袋里就会出来一个二叉树,每个元素往下分支,每一层有两个分叉,即该元素存在或者不存在,一直分叉到第n层,可得到2^n个叶节点。那么对于二叉树类型的题,用什么解法呢?递归呀!于是便有了下面的解法。其实当我写出这个解法的时候,就知道它注定不是最优解法了,因为必须另建递归体,还得声明一个全局变量,没办法,能力有限,稍后展示更优秀的解法。

class Solution {
public:
    vector<vector<int>>res;
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<int>work;
        process(0,nums.size(),nums,work);   
        return res;
    }
    void process(int pos,int n,vector<int>& nums,vector<int>& work){
        if(pos==n){
            res.push_back(work);
            return;
        }

        work.push_back(nums[pos]);
        process(pos+1,n,nums,work);

        work.pop_back();
        process(pos+1,n,nums,work);
    }
};

leetcode排第一的解法
其实看到这题,脑袋不该只想出来一个庞大的二叉树,应该还要想出来一个精巧的二进制体,这个二进制体有n位,如100;就代表第一个数被选中,装入[1],101,就代表1和3被选中,装入[1,3]。这个二进制体也可以表示2^n种情况。
我们可以初始化一个二维数组result,使其长度为2^n,然后遍历nums的每个位置i,再嵌套遍历result的每个位置j,计算j>>i & 1的值,若等于1,代表在第j种情况中,i位置的元素被选中,那就把这个元素装入result[j]里。于是有了以下解法:

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {


        int cnt = 0;
        int n = nums.size();
        int sub = pow(2, n);
        vector<vector<int>> result(sub, vector<int>());
        for(int i = 0; i < n; i ++)
        {
            for(int j = 0; j < sub; j++)
            {
                if(j>>i & 1)
                {
                    result[j].push_back(nums[i]);
                }
            }
        }


        return result;
    }

};

猜你喜欢

转载自blog.csdn.net/qq_36946274/article/details/80787406