【双指针方法】
- 对数组长度小于 3,直接返回。
- 对数组进行排序
- 遍历排序后数组:
- 若 nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 0,直接返回结果。
- 对于重复元素:跳过,避免出现重复解
- 令左指针 L=i+1,右指针 R=n−1,当 L<R时,执行循环:
- 当 nums[i]+nums[L]+nums[R]==0,执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L,R 移到下一位置,寻找新的解
- 若和大于 0,说明 nums[R]太大,R左移
- 若和小于 0,说明 nums[L]太小,L 右移
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
vector<int> temp(3);
if (nums.size()<3)return res;//长度小于3时直接返回
sort(nums.begin(), nums.end());//为了避免重复,所以要排序
int he = 0;
for (int i = 0; i < nums.size(); i++) {
if (nums[i] > 0)return res;//由于已经是从小到大排序,后面不再可能有等于0的情况
else if (i > 0 && nums[i] == nums[i - 1])continue;//跳过相同元素
int L = i + 1;
int R = nums.size() - 1;
while (L<R)
{
he = nums[i] + nums[L] + nums[R];
if (he == 0)
{
temp[0]=nums[i];
temp[1]=nums[L];
temp[2]=nums[R];
res.push_back(temp);
while (L<R&&nums[L + 1] == nums[L])L++;//去除重复元素
while (L<R&&nums[R - 1] == nums[R])R--;//去除重复元素,要记得加L<R,否则数组会越界
L++;
R--;
}
else if (he > 0)R--;
else if (he < 0)L++;
}
}
return res;
}
有一个问题是,为什么只在和是0的时候才消除重复元素呢?为什么和大于0和小于0都不消除重复元素呢?