这个问题是我从leetcode上一道问题所想到的,原题:如果是从数组中选出2个数相加使之成为固定的数sum,这当然很简单,把数组中的数字遍历一遍,判断另一个数字是否也在数组中即可。代码如下。
vector twoSum(vector& nums, int target) {
vector result;
map cache;//第一个为数字,第二个为下标
int max_index = nums.size()-1;
for (int i = 0 ; i <= max_index; i++)
{
cache[nums[i]] = i;
}
map::iterator iter;
for (int i = 0 ; i <= max_index; i++)
{
iter = cache.find(target - nums[i]);
if(iter != cache.end() && iter->second != i)
{
result.push_back(nums[i]);
result.push_back(iter->first);
break;
}
}
return result;
}
void CalSum(vector &nums, int result)
{
int len = nums.size();
int *dp = new int[result + 1];
dp[0] = 1;
for (int i = 1; i <= len; i++)
{
dp[i] = 0;
}
vector *p = new vector[result + 1];
for ( i = 0; i < len; i++)
{
for (int j = result; j >= nums[i]; j--)
{
if (dp[j] < dp[j - nums[i]])
{
dp[j] = dp[j - nums[i]];
p[j] = p[j-nums[i]];
p[j].push_back(nums[i]);
}
}
}
if (dp[result] == 1)//如果存在某些物品使得容量为result的背包恰好装满则输出。
{
for (vector::iterator iter = p[result].begin(); iter != p[result].end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
}
delete []dp;
delete []p;
}
void combination(vector& candidates, int start, int end, int target, vector &tmp, vector > &result)
{
if (target == 0)
{
result.push_back(tmp);
return;
}
if (start > end)//如果start超过end还没达到目标,那么就直接去掉
{
return ;
}
for (int i = start; i <= end; i++)
{
tmp.push_back(candidates[i]);
combination(candidates, i + 1, end, target - candidates[i], tmp, result);
tmp.pop_back();
while(i < end && candidates[i] == candidates[i+1])//去掉重复的组合
{
i++;
}
}
}
vector > CalSum(vector& candidates, int target) {
sort(candidates.begin(), candidates.end());
vector > result;
vector tmp;
int end = candidates.size() - 1;
combination(candidates, 0, end, target, tmp, result);
return result;
}
如果我们指定数字的个数m,只需要在push之前加一个判断:
if (target == 0)
{
if (tmp.size == m)
{
result.push_back(tmp);
}
return;
}
void CalSum(vector &nums, int result)
{
int len = nums.size();
int bit = 1 << len;
sort(nums.begin(), nums.end());//对数组排序
for (int i = 1; i < bit; )//从1循环到2^N
{
int sum = 0;
vector tmp;
for (int j = 0; j < len; j++)
{
if ((i & 1 << j) != 0)//用i与2^j进行位与运算,若结果不为0,则表示第j位不为0,从数组中取出第j个数
{
sum += nums[j];
tmp.push_back(nums[j]);
}
}
if (sum == result)
{
i = i | (i - 1);//剪枝优化
for (vector::iterator iter = tmp.begin(); iter != tmp.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
}
i++;
}
}
nt NumOf1(int num)
{
int count = 0;
while (num)
{
num = num & (num - 1);
count++;
}
return count;
}
void CalSum(vector &nums, int result, int m)
{
int len = nums.size();
int bit = 1 << len;
for (int i = 1; i < bit; i++)//从1循环到2^N
{
int sum = 0;
vector tmp;
if (NumOf1(i) == m)
{
for (int j = 0; j < len; j++)
{
if ((i & 1 << j) != 0)//用i与2^j进行位与运算,若结果不为0,则表示第j位不为0,从数组中取出第j个数
{
sum += nums[j];
tmp.push_back(nums[j]);
}
}
if (sum == result)
{
for (vector::iterator iter = tmp.begin(); iter != tmp.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
}
}
} }
参考: