题目:https://leetcode.com/problems/3sum/description/
题目
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] ]
Solution
C++
the key idea is the same as the TwoSum
problem. When we fix the 1st
number, the 2nd
and 3rd
number can be found following the same reasoning as TwoSum
.
The only difference is that, the TwoSum
problem of LEETCODE has a unique solution. However, in ThreeSum
, we have multiple duplicate solutions that can be found. Most of the OLE errors happened here because you could've ended up with a solution with so many duplicates.
The naive solution for the duplicates will be using the STL methods like below :
std::sort(res.begin(), res.end());
res.erase(unique(res.begin(), res.end()), res.end());
But according to my submissions, this way will cause you double your time consuming almostly.
A better approach is that, to jump over the number which has been scanned, no matter it is part of some solution or not.
If the three numbers formed a solution, we can safely ignore all the duplicates of them.
We can do this to all the three numbers such that we can remove the duplicates.
Here's my AC C++ Code:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
std::sort(nums.begin(),nums.end());
for(int i = 0;i<nums.size();i++){
int target = -nums[i];
int front = i+1;
int back = nums.size()-1;
while(front<back){
int sum = nums[front] + nums[back];
if(sum<target)
front++;
else if(sum>target)
back--;
else{
vector<int> triplet(3,0);
triplet[0] = nums[i];
triplet[1] = nums[front];
triplet[2] = nums[back];
res.push_back(triplet);
while(front<back && nums[front]==triplet[1]) front++;
while(front<back && nums[back]==triplet[2]) back--;
}
}
while(i+1<nums.size()&&nums[i+1] == nums[i]) i++;
}
return res;
}
};