给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组
//用数组存储数组,表示答案不唯一,不止有一个解,所以要用解集存储,解集,集
//<size时会有N个元素,<size-2时会有n-2个元素,即去掉了两个
//<size时下标止于N-1
//left<right时,最后会使left停在right的位置
//left+1<right时,会使left停在right前一个的位置
vector<vector<int>> func(vector<int>nums) {
vector<vector<int>>res;
sort(nums.begin(), nums.end());
for (int i = 0; i < nums.size() - 2; i++) {
if (i != 0 && nums[i] == nums[i - 1]) { continue; }//目标值也要去重
//第一项一定是不重的,所以i!=0,也是为了保证i-1不会越界
int left = i + 1, right = nums.size() - 1;
int target = -nums[i];//三数之和为0,则移项一个,让它的相反数作为目标值,即多一个指针指向的值,来映射当前的目标值
while (left < right) {//终止时left==right
int sum = nums[left] + nums[right];
if (sum > target) { right--; }
if (sum < target) { left++; }
if (sum == target) {
res.push_back({ nums[i],nums[left],nums[right] });
//考虑极端情况为左一片与右一片值都相同,且满足条件,那么会向数组中加很多组重复的数据,直到左右指针重合(此时不重合,而是交叠,因为动两个指针,left右移的同时,right左移)
//所以需要去重,即指针遇到同一片相同的数值时,就跳过,在遇到第一个且已做处理的情况下
//如果满足,则哪个动一下下一组都会不满足,如果不满足,那么这一组都不满足,或者使右指针动,直到满足,那么又到了前一种情况
//即相同的数据,只要一个来判断并记录就行
// 不需要每种情况都要去重,只要相等时就行,因为只有相等时才记录,在第一次记录后就把相同的情况全抹除
//由于最后会有left++,right--的统一操作,所以移动指针时,不要直接越过所有,而是要指向最后一个相同的元素,即判断语句nums[left]==nums[left+1]
//这样在left++后才可移到下一个不同的元素上
//一般情况下只有这个判断就够了
//但考虑极端情况,即左右的那片都相同,即合起来时一片,加起来还满足条件,那么左指针将一步冲天,直接到最后一个,再++还会越界
//所以需要保证在这种情况下也不会出问题就需要left+1<right,才可使左右指针在正常范围内移动,
while (left + 1 < right && nums[left] == nums[left + 1]) {//终止时left==right-1,即保证极端情况下左指针停在右指针前一个位置
left++;
}
while (right - 1 > left && nums[right] == nums[right--]) {
right--;
}
left++; right--;
}
}
}
return res;
}