我的思路:二进制位上有1则加

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        for(int i=0;i<pow(2,nums.size());++i)
        {
            vector<int> path;
            f(i,path,nums);
            res.push_back(path);
        }
        return res;
    }
    void f(int i,vector<int> &path,vector<int> &nums)
    {
    	auto c=nums.begin();
        while(i)
        {
        	int j=i%2;
        	i=i/2;
        	if(j==1)
        		path.push_back(*(c+j-1));
        	c++;
		}
		
    }
};

  16ms

二进制法
本方法的前提是:集合的元素不超过int 位数。用一个int 整数表示位向量,第i 位为1,则表示
选择S[i],为0 则不选择。例如S={A,B,C,D},则0110=6 表示子集{B,C}。
这种方法最巧妙。因为它不仅能生成子集,还能方便的表示集合的并、交、差等集合运算。设
两个集合的位向量分别为B1 和B2,则B1 [ B2;B1 \ B2;B1△B2 分别对应集合的并、交、对称差。
二进制法,也可以看做是位向量法,只不过更加优化。

class Solution {
public:
vector<vector<int> > subsets(vector<int> &S) {
sort(S.begin(), S.end()); // 输出要求有序
vector<vector<int> > result;
const size_t n = S.size();
vector<int> v;
for (size_t i = 0; i < 1 << n; i++) {
for (size_t j = 0; j < n; j++) {  //利用与 运算符,成功的探测到 每一位上是否是1 ....记住
if (i & 1 << j) v.push_back(S[j]);
}
result.push_back(v);
v.clear();
}
return result;
}
};

  8ms