题目
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
思路
- 先排序数组
- 参照快排,找出一个基准数(一般为左边第一个),然后定义两个指针分别指向基准数的右边一个和数组尾部;
- 如果基准数大于0,直接推出循环;
- 如果基准数小于0,判断基准数与两只指针数的和是否为0:
1:sum>0,右边界–;
2:sum<0,左边界++;
3:sum=0,存下当前三个数,同时做左右两边去重操作,防止出现重复数组
代码
class Solution {
public:
int partition(std::vector<int>& nums, int left, int right)
{
int num = nums.at(left);
while(left < right)
{
while(num <= nums.at(right) && left<right)
{
right--;
}
while(num > nums.at(left) && left<right)
{
left++;
}
if(left < right)
std::swap(nums.at(left),nums.at(right));
}
return left;
}
void qsort(std::vector<int>& nums, int left, int right)
{
if(left >= right)
return;
if(left < right)
{
int tempL = left;
int tempR = right;
int pos = partition(nums,left,right);
qsort(nums, tempL,pos);
qsort(nums, pos+1,tempR);
}
}
vector<vector<int>> threeSum(vector<int>& nums)
{
vector<vector<int>> res;
auto size= nums.size();
if(size<3)
return res;
if(size == 3)
{
if((nums.at(0) + nums.at(1) + nums.at(2)) == 0)
{
res.push_back(std::vector<int>{nums.at(0) , nums.at(1) , nums.at(2)});
return res;
}
return res;
}
//qsort(nums,0,size-1);
sort(nums.begin(), nums.end());
for(int i=0;i<size;i++)
{
if(nums.at(i)>0)
return res;
if(i>0 && nums.at(i) == nums.at(i-1))
continue;
int left = i+1;
int right = size-1;
while(left < right)
{
if(nums.at(i) + nums.at(left) + nums.at(right) >0)
right--;
else if(nums.at(i) + nums.at(left) + nums.at(right) <0)
left++;
else
{
res.push_back(std::vector<int>{nums.at(i) , nums.at(left) , nums.at(right)});
while(left<right && nums.at(right) == nums.at(right-1))
right--;
while(left<right && nums.at(left) == nums.at(left+1))
left++;
right--;
left++;
}
}
}
return res;
}
};