LeetCode #78. Subsets
求集合的所有子集
递归法
S(n) : 等于第n个元素与S(n-1)中的每个元素组成集合,外加{n}和全集。
vector<vector<int>> subsets(vector<int> &nums) {
vector<vector<int>> sets;
if (nums.size() == 0)
return{ {} };
else {
vector<int> ss{ nums };
int last = *(ss.end() - 1);
ss.erase(ss.end() - 1);
sets = subsets(ss);
int len = sets.size();
for (int i = 0; i < len; i++)
{
vector<int> tmp = sets[i];
tmp.push_back(last);
sets.push_back(tmp);
}
}
return sets;
}
复杂度
T(n) = 2T(n-1)+2;
位运算
对N个元素,让每个元素对应N的2进制表示中的一位。某位为0,则不在子集;为1,则在子集中。
void subset(int arr[], int len)
{
int mask = 0, i = 0;
int end = (1 << len) - 1; //各位均为1, 2^n-1
bool nullset = false;
for (mask = 0; mask <= end; mask++) //循环2^n次
{
nullset = true;
for (i = 0; i < len; i++) //循环n次
{
if (((1 << i)&mask) != 0)
{
nullset = false;
cout << arr[i]<<", ";
}
}
if (nullset)
cout << "@, ";
cout << endl;
}
}
复杂度
类似字符串的子序列,N位,每位有2种状态,对应个数为
2n
个。
整体复杂度为
O(n∗2n)
。
后记
其实N个元素的子集:
C0n+C1n+...+Cnn
由二项式定理,也可以得到 2n
感觉自己好傻逼啊。囧