15.三数之和
思路
先把数组排序
先枚举i,再枚举j,确定了i和j的值,在保证\(nums[i] + nums[j] + nums[k - 1] >= 0\)的条件下,找到k的最小值,之后查看三数相加是否等于0,如果相等,记录答案,如果不等,那就继续枚举i和j
这里的j和k的确定使用的是双指针做法,因为有序,因此每次j增大,k必然要减小
Q1 如何去重?
以任意数组为例,开始时令i等于第一个元素,当枚举完j和k后,此时可以说,所有i = 第一个元素
的方案都已经考虑过了,因此i要跳过后面所有等于第一个元素的值,j也是同样的道理,这样就能够做到去重
代码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans;
sort(nums.begin(), nums.end());
for(int i = 0; i < nums.size(); i++)
{
if(i && nums[i] == nums[i - 1]) continue;
int j = i + 1, k = nums.size() - 1;
while(j < k)
{
if(j > i + 1 && nums[j] == nums[j - 1])
{
++j;
continue;
}
int val = nums[i] + nums[j] + nums[k];
if(val == 0) ans.push_back({nums[i], nums[j], nums[k]});
//此处必须是++j,不能换成--k,因为需要用j完成去重
if(val <= 0) ++j;
else --k;
}
}
return ans;
}
};