题目介绍
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:
Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
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)
解法
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 front=i+1;
int j=nums.size()-1;
while(front<j){
if(nums[i]+nums[front]+nums[j]<0){
front++;
}else if(nums[i]+nums[front]+nums[j]==0){
vector<int> v(3,0);
v[0] = nums[i];
v[1] = nums[front];
v[2] = nums[j];
res.push_back(v);
while (front<j&&nums[front] == v[1]) front++;
while(front <j&&nums[j]==v[2]) j--;
}else{
j--;
}
// avoid time limited;
while(i+1<nums.size()&& nums[i]==nums[i+1]) i++;
}
}
return res;
}
思路
- 外循环使用变量i表示当前元素,front=i+1; j=nums.size()-1双指针控制front, j分别代表头部和尾部;
- 判断nums[i]+nums[front]+nums[j]与0的关系:
- 当nums[i]+nums[front]+nums[j] < 0;表示负数,front需要后移;
- 当nums[i]+nums[front]+nums[j] == 0;保存结果;
- 当nums[i]+nums[front]+nums[j] > 0; 表示结果为正,j需要前移。
- 在步骤2中要保证front < j.
总结
- 使用两个指针夹逼控制判断;
- 在遍历的时候,开始都需要对双指针进行赋值,而不是在循环中直接转移,比如[-1,-1,0,-2,2],对于尾部指针可能存在[-2,0,2],[-1,-1,2];
- 之前测试中,出现时间超时,应该在遍历时对于双指针临近有相同元素值的时候直接跳过,加快时间。
- 在判断过程中保证front < j