Given a set of distinct integers, S, return all possible subsets.
Note:
- Elements in a subset must be in non-descending order.
- The solution set must not contain duplicate subsets.
For example,
If S = [1,2,3]
, a solution is:
[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
Given a set of distinct integers, S, return all possible subsets.
这道题采用递归方式比较方便,具体可以参考网上其他人给出的答案。
这里我采用非递归方式完成这道题。
若S大小为n,构造一个大小为n+1的位图,0~n-1位为0或者1分别表示S中对应数字加入或者不加入集合两种情况,共有2^n中情况,位图从0开始递增1,每个位图值就对应一种可能的情况,根据位图值选取集合中的数字就构成一种可能情况加入到最终结果中。当位图的第n位为1时,表示所有可能情况都取到了,程序结束。
算法的复杂度较递归算法没有提升,这里只是提供另外一种思路。
AC code:
class Solution {
public:
vector<vector<int> > subsets(vector<int> &S)
{
vector<vector<int>> ret;
int n = S.size();
if (n == 0)
return ret;
int int_size = sizeof(int)* 8;
int *flag = new int[(n + 1) / int_size + 1]; //多分配了一个1bit大小,方便做结束判断
memset(flag, 0, ((n + 1) / int_size + 1)*sizeof(int));
vector<int> temp;
while ((flag[(n + 1) / int_size] & (1 << n % int_size)) == 0)
{
temp.clear();
for (int i = 0; i < n; i++)
{
if ((flag[i / int_size] & (1 << i%int_size)) != 0)
temp.push_back(S[i]);
}
sort(temp.begin(), temp.end());
ret.push_back(temp);
int j = 0;
while (1) //加1操作
{
if (flag[j] != INT_MAX)
{
++flag[j];
break;
}
else
flag[j++] = 0;
}
}
return ret;
}
};