3 Sum 三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
输入:
nums = [-1, 0, 1, 2, -1, -4],
输出:
[
[-1, 0, 1],
[-1, -1, 2]
]
方法一:双指针法
如果我们随机确定了一个数a,问题就变成了,在剩下的数里面找到2个数和为0-a,和2SUM问题一样了?(还需要排除重复答案)。
思路:
首先确保数组有序。
用指针i确定一个数a。用j和p两个指针分别从两端到中央扫描,如果指针所指的值之和与0-a相比较小,那就需要j右移,反之p左移。
时间复杂度O(N2):其中固定指针i循环复杂度 O(N),双指针 j, p 复杂度 O(N)。排序时间复杂度O(NlogN)。
vector<vector<int>> threeSum(vector<int>& nums) {
if (nums.size()<3) return {};
vector<vector<int>> res;
sort(nums.begin(),nums.end());
//首先确保数组有序
for(int i=0;i<=nums.size()-3;i++) {
if (nums[i]>0) break;
if (i > 0 && nums[i] == nums[i - 1]) continue;
int j=i+1,p=nums.size()-1;
while(j<p){
if(nums[j]+nums[p]+nums[i]==0)
{ res.push_back({nums[i],nums[j],nums[p]});
//跳过重复匹配
while (j < p && nums[j] == nums[j + 1]) j++;
while (j < p && nums[p] == nums[p - 1]) p--;
p--;j++;
}
else if(nums[j]+nums[p]+nums[i]<0) j++;
else p--;
}
}
return res;
}