Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
- Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
- The solution set must not contain duplicate triplets.
For example, given array S = {-1 0 1 2 -1 -4}, A solution set is: (-1, 0, 1) (-1, -1, 2)本题首先确定一个元素,随后在剩余元素中找和为固定值的两个元素,这可以采用twoSum中的思路。本题的难点在于如何排除重复的情况,并且在排除重复时不能把正确的情况也排除掉。
功能测试用例:{-1,0,0,1,1,2,-1,-4}
特殊测试用例:{},{0},{0,1},{0,0,0,0,0}
具体代码如下:
class Solution { public: void FastSort(vector<int> &vsNumber, int nBegin, int nEnd)//快速排序 { if (nBegin >= nEnd) return; int nPos1 = nBegin; int sNMiddle = vsNumber[nEnd], sNChange; for (int nPos2 = nBegin; nPos2 < nEnd; nPos2++) { if (vsNumber[nPos2] < sNMiddle) { sNChange = vsNumber[nPos1]; vsNumber[nPos1] = vsNumber[nPos2]; vsNumber[nPos2] = sNChange; nPos1++; } } vsNumber[nEnd] = vsNumber[nPos1]; vsNumber[nPos1] = sNMiddle; FastSort(vsNumber, nBegin, nPos1 - 1); FastSort(vsNumber, nPos1 + 1, nEnd); } vector<vector<int> > threeSum(vector<int> &num) { vector<vector<int>> vvnResult; vector<int> vnMiddle(3); if (num.size() < 3)//如果输入向量少于3个元素,则返回空向量 { return vvnResult; } int nBegin, nEnd, nRemain; FastSort(num,0,num.size()-1);//对输入向量快速排序 for (int nTemp = 0; nTemp < num.size() - 2; nTemp++)//遍历排序后从第一个到倒数第三个元素 { if (nTemp > 0 && num[nTemp] == num[nTemp - 1])//如果当前元素与前一个元素重复,则跳出本次循环继续下一次循环 continue; nRemain = 0 - num[nTemp]; nBegin = nTemp + 1; nEnd = num.size() - 1; while (nBegin < nEnd) { if (num[nBegin] + num[nEnd] == nRemain)//判断三个元素的和等于0 { if (nBegin != nTemp + 1 && num[nBegin] == num[nBegin - 1])//去重复情况 { nBegin++; } else if (nEnd != num.size() - 1 && num[nEnd] == num[nEnd + 1])//去重复情况 { nEnd--; } else { vnMiddle[0] = num[nTemp]; vnMiddle[1] = num[nBegin]; vnMiddle[2] = num[nEnd]; vvnResult.push_back(vnMiddle); nBegin++; nEnd--; } } else if (num[nBegin] + num[nEnd] < nRemain) { nBegin++; } else { nEnd--; } } } return vvnResult; } };