题目链接:三数之和
因为要求使a+b+c=0的三元组,因此先将数组s进行排序
sort(A.begin(),A.end());
又因为不能使结果包含重复的三元组,所以定义一个set判断此三元组是否在之前出现过
//用于接收和=0的三元组
pair<pair<int,int>,int> x;
//储存三元组
set<pair<pair<int,int>>> mp;
之后定义left,right,让left=i+1,right = 数组长度-1,之后对A[i]+A[left]+A[right]的和进行判断,如果大于零则让right的值向前移一位right-1,如果小于零则令left+1,当left>=right时结束此次循环,进行下次循环,如果A[right] = A[right-1],为了防止出现重复解,可以令right-1,直到不相等为止,对于left一样,让left+1直到不相等。
完整代码:
class Solution {
public:
/**
* @param numbers: Give an array numbers of n integer
* @return: Find all unique triplets in the array which gives the sum of zero.
*/
vector<vector<int>> threeSum(vector<int> &A) {
// 求数组的长度
int len = A.size();
//储存三元组
vector<vector<int>> ans;
//判断三元组是否出现过
set<pair<pair<int,int>,int>> flag;
//保存三元组用于
pair<pair<int,int>,int> x;
//对数组进行排序
sort(A.begin(),A.end());
//如果数组长度小于三,直接返回ans,因为不可能有三个数相加等于0
if(len < 3)
return ans;
//left为左指针,right为右指针
int left,right;
for(int i = 0;i<len;i++)
{
//让left = i的下一位
left = i+1;
//right从最右边开始计算
right = len-1;
//当A[i]大于0时表名i的后面全为大于0的值因此不可能出现等于0的情况,直接返回ans即可
if(A[i]>0)
return ans;
//当三数之和不为0时进行判断
while((A[i]+A[left]+A[right])!=0)
{
//如果三数之和>0表名右指针值太大,令其左移
while((A[i]+A[left]+A[right])>0)
right--;
//如果三数之和<0表名左指针值太小,令其右移
while((A[i]+A[left]+A[right])<0)
left++;
//如果left>=right退出循环
if(left>=right)
break;
}
if(left>=right)
continue;
while((A[i]+A[left]+A[right])==0)
{
//pair<pair<int,int>,int> x;
//x.fist为最内层的pair,其包括x.first.first与x.first.second
//x.second则为外层pair的second
x.first.first = A[i];
x.first.second = A[left];
x.second = A[right];
//set<pair<pair<int,int>,int>> flag;
//如果x在此之前没有出现过那么flag.count(x)的值为0
//否则为1
if(flag.count(x)==0)
{
//如果此前没有出现过这个三元组,则将其储存在flag中
flag.insert(x);
//将这个结果存入ans中
ans.push_back({A[i],A[left],A[right]});
}
//如果此前已经出现过则进行判断
else if(flag.count(x)==1)
{
while(A[left] == A[left+1])
{
left++;
if(left == len-1)
break;
}
while(A[right] == A[right-1])
right--;
if(left>=right)
break;
left++;
right--;
}
while((A[i]+A[left]+A[right])!=0)
{
while((A[i]+A[left]+A[right])>0)
right--;
while((A[i]+A[left]+A[right])<0)
left++;
if(left>=right)
break;
}
if(left>=right)
break;
}
}
return ans;
}
};