您的位置:首页 > 其它

求数组中若干个元素之和等于给定值

2016-03-19 15:52 260 查看
这个问题的基础版本是:在数组中找两个元素,使其之和等于某个给定值。解法简单:将数组排序后,用两个指针分别位于数组首与数组尾,然后计算两个指针所指元素的和,若大于给定的元素,则尾部的指针向前移动;若小于给定的元素,则首部的指针向后移动。

但该问题提升后,成为了子集和问题,这是一个NP问题。在leetcode上还有升级版本的问题:求给定数组中四个元素之和等于给定元素的所有元素的子集。该问题,只能用暴力搜索,加点启发式的暴力搜索,在数量到两个数之后用上述的两数之和的方法。

看了一个作者的博客里面的例子,理解了在数组中找若干个元素之和等于给定值的方法。作者博客见:点击打开链接

举一个简单的适合自己理解的例子:

数组为: [1,2,3,4,5,6]。找给定值 12 。元素个数不限定,只要找到的元素之和=12即可

初始化栈:

【1】 栈中元素和为 1 < 12。压入 1 的下一个元素 2

【1,2】 栈中元素和为 3 < 12 。压入 2 的下一个元素 3

【1,2,3】 栈中元素和为 6 < 12 。压入 3 的下一个元素 4

【1,2,3,4】 栈中元素和为 10 < 12 。压入 4 的下一个元素 5

【1,2,3,4,5】
栈中元素和为 15 > 12。则将栈顶元素 5 出栈,并将新的栈顶元素 4 扩大为位于其后的值

【1,2,3,5】 栈中元素和为 11 < 12。压入 5 的下一个元素 6

【1,2,3,5,6】
栈中元素和为 17 > 12。则将栈顶元素 6 出栈,并将新的栈顶元素 5 扩大为位于其后的值

【1,2,3,6】 栈中元素和为 12 = 12。则结束程序,栈中的元素即为找到的子集

实现代码如下:

vector<int> addSum(vector<int> & v,int dest_sum)
{
typedef int Value;
typedef int Loc;
std::sort(v.begin(), v.end());
stack<pair<Value,Loc>> sta;
int loc = 0;
int init_loc = 0;
int sum = v[loc];
sta.push({ v[loc],loc});
++loc;
while (sum != dest_sum)
{
if (loc < v.size() && sum + v[loc] <= dest_sum)
{
sum += v[loc];
sta.push({ v[loc], loc });
++loc;
}
else
{
if (!sta.empty())
{
auto v = sta.top();
sum -= v.first;
sta.pop();
loc = v.second + 1;
}
else
{
sum = 0;
loc = ++init_loc;
}
}
}

vector<int> res;
while (!sta.empty())
{
res.push_back(sta.top().first);
sta.pop();
}
return res;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息