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

来源:互联网 发布:北京交通大学知行论坛 编辑:程序博客网 时间:2024/05/20 05:04

leetcode上的原题,美图的笔试题目。

本质上这个问题是2数之和的问题扩展:

在给定的数组中找出两个数a,b,使得a+b=sum。

三个数之和为0,即a+b+c=0,可以转化为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中。

set<vector<int>> find_triplets(vector<int> arr){sort(arr.begin(), arr.end());set<vector<int>>ret;vector<int>temp(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{temp[0] = arr[i];temp[1] = arr[j];temp[2] = arr[k];ret.insert(temp);++j;--k;}}}return ret;}


可以不使用容器set去重复,循环时跳过重复相同的数。

vector<vector<int>> find_triples(vector<int>arr){sort(arr.begin(), arr.end());vector<vector<int>>ret;int n = arr.size();for (int i = 0; i < n-2; ++i){if (i == 0 || (i > 0 && arr[i] != arr[i - 1])){int lo = i + 1, hi = n - 1;int sum = 0 - arr[i];while (lo < hi){if (arr[lo] + arr[hi] == sum){ret.push_back({ arr[i], arr[lo], arr[hi] });while (lo < hi && arr[lo] == arr[lo + 1])++lo;//跳过重复值while (lo < hi && arr[hi] == arr[hi - 1])--hi;++lo;--hi;}else if (arr[lo] + arr[hi] < sum)++lo;else--hi;}}}return ret;}


 

 

0 0
原创粉丝点击