1、无重复元素的组合
在给出一组无重复的数据,如何求出其所有的组合,假如有n个数据,每个数据只有取和不取两种情况,其算法的伪代码表示为
combine(i, nums[], n) //其中n表示数组nums[]的长度,i表示当前数组的下标(即第i个元素)
if i== n then
return [] //[]表示空集合
[A1…An]= combine(i+1, nums[], n) //A1表示其中的一个集合,[A1…An]表示从i+1到n元素
之间生成的所有的组合
Ret= []
forA in [A1, …, An]
add A to Ret
add nums[i] to A
add A to Ret
return Ret
主要代码如下
vector<vector<int>> dfs(int cur, vector<int>& nums)
{
int n = nums.size();
if (cur >= n) {
vector<int> subset;
vector<vector<int>> ret;
ret.push_back(subset);
return ret;
}
vector<vector<int>> medium = dfs(cur + 1, nums);
vector<vector<int>> ret;
for (int i = 0, len = medium.size(); i < len; i++) {
ret.push_back(medium[i]);
medium[i].push_back(nums[cur]);
ret.push_back(medium[i]);
}
return ret;
}
vector<vector<int>> subsets(vector<int>& nums)
{
sort(nums.begin(), nums.end(), greater<int>());
return dfs(0, nums);
}
2、有重复元素的组合
有重复元素情况下,针对一个元素,就不是取和不取,就是取几个问题,伪代码描述如下
combine(i, nums[], count[],n)//这里nums[]表示没有重复元素的数据,count[]表示每个元素出现的次数
ifi == n then
return[]
[A1…An]= combine(i+1, nums, count, n)
Ret= [A1…An]
forA in [A1, …, An]
for j = 0 to count[i]
add nums[i] to A
addA to Ret
returnRet
主要代码如下
vector<vector<int>> dfs(int cur, vector<int>& nums, map<int, int>& m)
{
int n = nums.size();
if (cur >= n) {
vector<int> subset;
vector<vector<int>> ret;
ret.push_back(subset);
return ret;
}
vector<vector<int>> medium = dfs(cur + 1, nums, m);
vector<vector<int>> ret;
for (vector<int> v : medium) {
ret.push_back(v);
for (int j = 0; j < m[nums[cur]]; j++) {
v.push_back(nums[cur]);
ret.push_back(v);
}
}
return ret;
}
vector<vector<int>> subsetsWithDup(vector<int>& nums)
{
sort(nums.begin(), nums.end(), greater<int>());
map<int, int> m;
for (int num : nums) {
m[num]++;
}
nums.erase(unique(nums.begin(), nums.end()), nums.end());
return dfs(0, nums, m);
}