题目描述:给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:给定数组 nums = [-1, 0, 1, 2, -1, -4],满足要求的三元组集合为:[ [-1, 0, 1],[-1, -1, 2] ]
思路:
- 首先对数组进行排序,排序后固定一个数 target,再使用左右指针指向 target 后面的两端,数字分别为 nums[l] 和 nums[r] ,计算三个数的和sum ,判断是否满足为 0 ,满足则添加进结果集
- 如果 target大于 0 ,则三数之和必然无法等于 0 ,结束循环;
- 如果 nums[i] == nums[i−1],则说明该数字重复,会导致结果重复,所以应该跳过;
- 当 sum == 0 时,nums[l] == nums[l+1] 则会导致结果重复,应该跳过,l++;
- 当 sum == 0 时,nums[r] == nums[r-1] 则会导致结果重复,应该跳过,r-- ;
- 当sum>0时,r--;
- 当sum<0时,l++;
- 时间复杂度:O(n^2),n 为数组长度
代码如下:
vector<int>> threeSum(vector<int>& nums) {
int target;
vector<vector<int>> ans;
sort(nums.begin(),nums.end()); //先对数组进行排序
for(int i=0;i<nums.size();i++){
if(i>0&&nums[i]==nums[i-1]) //过滤重复数字
continue;
if((target=nums[i])>0) //target赋值为nums[i],并判断target是否大于0,如果大于0说明都不合适
break;
int l=i+1,r=nums.size()-1;
while(l<r){
if(nums[l]+nums[r]+target<0)
++l;
else if(nums[l]+nums[r]+target>0)
--r;
else{
ans.push_back({target,nums[l],nums[r]}); //符合条件
++l,--r;
while(l<r&&nums[l]==nums[l-1]) //从后往前跳过重复数字
++l;
while(l<r&&nums[r]==nums[r+1]) //从前往后跳过重复数字
--r;
}
}
}
return ans;
}
};