求数组中若干个元素之和等于给定值
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;
}
但该问题提升后,成为了子集和问题,这是一个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;
}
相关文章推荐
- 任意长度的高精度大整数加法
- 面试算法题:数组中两个数之和为定值,找出这对数的下标
- 解决批量修改AD域客户端管理员密码
- 问题:XMLHttpRequest cannot load file~~Origin 'null' is therefore not allowed access
- Eclipse加入PHP插件并支持PHP自动提示
- 单链表的C++实现
- hibernate实现增删改查的各种方法
- android studio提示 Plugin with id "com.android.library" not found解决方法
- 使用纯CSS3实现一个日食动画
- 常见数据格式
- 微生物增殖
- 第四周项目一 求任意四个数的公约数
- SSL协议以及握手过程
- 上海某生态农庄一游
- 电子数字
- hdu3336 Count the string--KMP+DP
- ARM寄存器
- poj2728
- (5)排序算法——快速排序
- 2016年3月18日 软件工程_东师站_课堂笔记