欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

在数组中找出3个数使得它们和为0

发布时间:2025/4/14 编程问答 47 豆豆
生活随笔 收集整理的这篇文章主要介绍了 在数组中找出3个数使得它们和为0 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

题目:

给定一个集合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)。该算法代码如下: [cpp] view plaincopy
  • /*k为和,a为元素数组,n为数组大小*/  
  • [cpp] view plaincopy
  • 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数和问题。这里稍有不同的是,上面问题的和K不一定是数组中的元素,它只是程序指定的一个参数。而在3数和问题中,如果转化为a+b=-c的问题,还需要保证-c在数组中。下面代码采用了两个循环,第一个循环代表初始值,即先是第一个值a[0]不变,计算a[0]+a[1]+a[n-1],若大于0则k减1,计算a[0]+a[1]+a[n-2],若小于0则j加1,计算a[0]+a[2]+a[n-1]...如果存在多个重复值,这可能会加入重复的数对,不过使用数据结构set可以解决该问题,相同的数对不会出现在set中。 [cpp] view plaincopy
  • 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 i = 0;i < n; i++) {  
  •     int j = i + 1;  
  •     int k = n - 1;  
  •     while (j < k) {  
  •       int sum_two = arr[i] + arr[j];  
  •       if (sum_two + arr[k] < 0) {  
  •         j++;  
  •       } else if (sum_two + arr[k] > 0) {  
  •         k--;  
  •       } else {  
  •         triplet[0] = arr[i];  
  •         triplet[1] = arr[j];  
  •         triplet[2] = arr[k];  
  •         triplets.insert(triplet);  
  •         j++;  
  •         k--;  
  •       }  
  •     }  
  •   }  
  •   return triplets;  
  • }  


  • 总结

    以上是生活随笔为你收集整理的在数组中找出3个数使得它们和为0的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。