题目描述
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:输入:nums = []
输出:[]
示例 3:输入:nums = [0]
输出:[]
解题方法
排序加双指针
排序是为了避免出现相同的方案。
解题步骤是:
(1)对所给数组从小到大进行排序
(2)从左到右遍历数组,取遍历元素x
(3)设置两指针i,j,初始时,i指向x右边元素,j指向最后一位元素。
(4)设i指向元素为y,j指向元素为z,若x+y+z = 0。将{x、y、z}加入结果集中,同时令i+1,j-1。否则,若x+y+z > 0,说明结果大了,此时需要让j--,让结果变小,若x+y+z < 0,说明结果小了,此时需要让i++,让结果变大。当i > j时,跳出循环回到(2)
代码
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> results;
int result;
if (nums.size() < 3) return results;
sort(nums.begin(),nums.end());
auto last = nums.end();
for (auto i = nums.begin();i < last - 2;++i){
auto j = i+1;
if (i>nums.begin()&&*i == *(i-1)) continue;
auto k = last-1;
while (j < k){
result = *i + *j + *k;
if(result < 0){
++j;
while(*j == *(j-1) && j < k) j++;
}else if(result > 0){
--k;
while(*k == *(k+1) && j < k) k--;
}else{
results.push_back({*i,*j,*k});
++j;
--k;
while(*j == *(j-1) && j < k) j++;
}
}
}
return results;
}
};