57. 三数之和关注问题
链接:https://www.lintcode.com/problem/3sum/description
描述
给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组。
在三元组(a, b, c),要求a <= b <= c。
结果不能包含重复的三元组。
样例
例1:
输入:[2,7,11,15]
输出:[]
例2:
输入:[-1,0,1,2,-1,-4]
输出:[[-1, 0, 1],[-1, -1, 2]]
思路:简单的思路就是三重循环暴力寻找,但是如果我们定下来了a、b,我们就可以计算出c = 0 - a - b,那么如果我们将数组变为有序,此时只需要查找元素,可以直接O(logn),当然也可以使用Hash,但是由于每个元素只能用一次,需要判断元素使用个数是否超出限制。另外为了解决重复序列的冲突,我们需要一个Hash(string)对答案进行去重。
class Solution {
public:
/**
* @param numbers: Give an array numbers of n integer
* @return: Find all unique triplets in the array which gives the sum of zero.
*/
string NumToString(int num){
if( num == 0 ) return "0";
string numString;
while(num){
numString += (num % 10) + '0';
num /= 10;
}
//是否正序其实无所谓 因为如果是同一个答案,那么序列一定一样,因为是按照a<=b<=c存储的
//reverse(numString.begin(),numString.end());
return numString;
}
vector<vector<int>> threeSum(vector<int> &numbers) {
// write your code here
unordered_set<string> hash_set;
vector<vector<int> > ans;
string mapValue;
sort(numbers.begin(),numbers.end());
int n = numbers.size(), i, j, m;
vector<int>::iterator iter;
for(i = 0; i < n; ++ i){
for(j = i + 1; j < n - 1; ++ j){
iter = lower_bound(numbers.begin() + j + 1,numbers.end(), 0 - numbers[i] - numbers[j]);
mapValue = NumToString(numbers[i]) + "#" + NumToString(numbers[j]) + "#" + NumToString(*iter) ;
if( *iter == 0 - numbers[i] - numbers[j] && hash_set.find(mapValue) == hash_set.end() ){
hash_set.insert(mapValue);
vector<int> temp;
temp.push_back(numbers[i]);
temp.push_back(numbers[j]);
temp.push_back(*iter);
ans.push_back(temp);
}
}
}
return ans;
}
};