题目
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2, -1, -4],
A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
解答
看这个题目,首先想到的是暴力枚举,不过做完之后看了网上的一些解答,好像暴力枚举确实是可以的。
但是作为一个可爱的娃的爸爸,我肯定是先想到排序,这样就算是暴力枚举,应该也会方便一丢丢?
不管怎么样先做个排序,排序完之后就要冷静的想一想这个问题的本质,毕竟除了3sum,这个题还可以出成4sum,5sum什么的。
我们知道,如果把这个题目改成求2sum,那么就很简单了,从头开始遍历,先确定第一个数,确定了第一个数后从尾开始遍历,不断尝试第二个数。
那么我们就可以递归的来思考这个问题,我们可以把这个问题看成,找到所有由一个数和一个2sum构成的组合,这样就很简单了。
于是我们同样从头开始遍历,先确定第一个数a,然后问题就变成,在a后面的数组中,求2sum,且2sum的和为-a。
下面是AC的代码,可能我细节方面做的还不够好,我的这个解法只能击败80%的答题者:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
int i, j, k, m;
int length = nums.size();
int temp;
vector<vector<int>> ans;
if(length == 0){
return ans;
}
sort(nums.begin(), nums.end());
if(nums.front() > 0 || nums.back() < 0){
return ans;
}
for(i = 0; i < length - 2; i++){
if(i > 0 && nums[i - 1] == nums[i]){
continue;
}
for(j = i + 1, k = length - 1; j < k; ){
if(nums[i] + nums[j] + nums[k] == 0){
vector<int> temp;
temp.push_back(nums[i]);
temp.push_back(nums[j]);
temp.push_back(nums[k]);
ans.push_back(temp);
j++;
while(j < k && nums[j] == nums[j - 1]){
j++;
}
k--;
while(j < k && nums[k] == nums[k + 1]){
k--;
}
}
else if(nums[i] + nums[j] + nums[k] < 0){
j++;
}
else{
k--;
}
}
}
return ans;
}
};
101