在数组中找出3个数使得它们和为k
来源:互联网 发布:逆战一键瞬狙宏软件 编辑:程序博客网 时间:2024/05/20 02:28
转自:http://blog.csdn.net/yunzhongguwu005/article/details/9187161
题目:
给定一个集合S,试找出3个数a, b, c,使得a+b+c=0。也即从集合中找出所有的和为0的3个数。
例如:集合S={-1,0, 1, 2, -1, 4},则满足条件的3个数有2对:(-1, 0, 1)和(-1, 2, -1)。注意(-1,1,0)与(-1,0,1)算同一个解,所以不用重复考虑。当然该例子集合的解也可以写成:(0, 1, -1)和(2, -1, -1)。
解法:
这个问题也被称作3数和问题,3数和问题是下面这个问题的扩展。
问题:给定一个n个元素的集合S,找出S中满足条件的整数对A,B, 使得A+B=K。
假定集合S已经排好序的话,则上面这个问题可以在O(n)的时间内解决。使用2个索引值first和last,分别指向第一个元素和最后一个元素,设指向的第一个元素为A,则我们的任务就是找到对应于A的元素B,B=K-A。如果last指向的元素小于B,则first加1,指向后面的一个元素;如果last指向的元素大于B,则last减1。这样最终一步步逼近结果,时间复杂度为O(n)。该算法代码如下:
- /*k为和,a为元素数组,n为数组大小*/
- void findsum(int k, int a[], int n)
- {
- bool found = false;
- sort(a, a+n); //对数组排序
- int i=0, j=n-1;
- while (i < j) {
- if (a[i] + a[j] < k) //和小于K,则i++
- i++;
- else if (a[i] + a[j] > k) //和大于K,则j--
- j--;
- else { // 找到了,a[i]+a[j]=k
- cout << "find " << a[i] << "+"
- << a[j] << "=" << k << endl;
- i++;
- j--;
- found = true;
- }
- }
- if (!found)
- cout << "not found" << endl;
- }
在上面这个解法的基础上,我们可以在O(n^2)的时间内解决3数和(A+B+C=k)问题。这里稍有不同的是,上面问题的和K不一定是数组中的元素,它只是程序指定的一个参数。而在3数和问题中,如果转化为a+b=k-c的问题,还需要保证k-c在数组中。下面代码采用了两个循环,第一个循环代表初始值,即先是第一个值a[0]不变,计算a[0]+a[1]+a[n-1],若大于k则i减1,计算a[0]+a[1]+a[n-2],若小于k则j加1,计算a[0]+a[2]+a[n-1]...如果存在多个重复值,这可能会加入重复的数对,不过使用数据结构set可以解决该问题,相同的数对不会出现在set中。
- set<vector<int> > find_triplets(vector<int> arr)
- {
- sort(arr.begin(), arr.end());
- set<vector<int> > triplets;
- vector<int> triplet(3);
- int n = arr.size();
- for (int m = 0;m < n; m++) {
- int j = m + 1;
- int i = n - 1;
- while (j < i) {
- int sum= arr[m] + arr[j]+arr[i];
- if (sum < k) {
- j++;
- } else if (sum> 0) {
- i--;
- } else {
- triplet[0] = arr[m];
- triplet[1] = arr[j];
- triplet[2] = arr[i];
- triplets.insert(triplet);
- j++;
- i--;
- }
- }
- }
- return triplets;
- }
0 0
- 在数组中找出3个数使得它们和为k
- 在数组中找出3个数使得它们和为k
- 在数组中找出3个数使得它们和为0
- 在数组中找出3个数使得它们和为0
- 在数组中找出3个数使得它们和为0
- 在一个数组中找两个数,使得它们的和为一个指定的数
- 找出数组中最小的 K 个数
- 在数组中查找两个数,使得它们的和正好是输入的那个数字
- 在数组中查找两个数,使得它们的和正好是输入的那个数字。
- 在一个数组中找一个三元组,使得它们的和等于指定值
- 从数组中选择m个数,使得和为sum,递归写法
- 【查找】在按照绝对值排序的数组中,找出和为k的两个数的下标
- 14.在数组中查找两个数,使得它们的和正好是输入的那个数字
- 14 在数组中查找两个数,使得它们的和正好是输入的那个数字
- 在升序数组中查找两个数,使得它们的和正好是输入的那个数字
- 有序数组a,b,找出a,b(合并为一个大的有序数组后)中第k个数
- 找出无序数组中最小的前k个数
- 使用二分法从数组中找出最小的k个数
- Doubles
- CSS3选择器——2、层次选择器
- hdu2859---Phalanx
- 只言片语 - 唯美图片与优美文字的完美结合
- Android事件传递机制
- 在数组中找出3个数使得它们和为k
- web开发之即时通讯数据库设计
- 自定义Label
- OpenCV中findFundamentalMat函数使用的模型
- Android AIDL运用总结
- Android如何防止apk程序被反编译
- sgu326 贪心+dinic
- 情人节网站logo赏析
- C++中 模板Template的使用