タイトル
3つの要素はNUMSよう+ B + C = 0で、B、C、N個の整数の配列NUMSれる所与?ゼロの合計を与え、アレイ内のすべてのユニークなトリプレットを検索します。
注意:
ソリューション・セットは、重複三つ子を含めることはできません。
例:
>配列NUMS = [-1、0、1、2、-1、-4]が与えられると、
解集合である
:[[-1、0、1]、[ - 1、-1、2]]
考え
方法ダブルポインタ変異体 - 三針法(本明細書ポインタ添字の配列を意味します)
- 3つの数字を確実にするために、A + B + C = 0。
- 少なくともゼロまたは負の数であることを保証するために、
- しかし、アレイは無秩序に配置されているので、直接に0または負であるか否かを決定することは困難であり、次いで、アレイ考えをソート
- 式はどのように見つけるためにB + C = -a、として書き直されます
- まず、正の数(0または負)を確保するために非
- どのように-aすることを等しくするためにbとcを見つけるには?
- 中間ポインタP2、テールポインタP3を規定する、中間体の移動方向に移動させます
- 中間ポインタP2、テールポインタP3を規定する、中間体の移動方向に移動させます
- 結果が重複することはできません
- 、デジタル飛ばし判断された場合には最も外側のループ
- P2、P3真ん中に移動し、反復要素をスキップ
こうして
ステップ1:配列ソート
:ステップ2が正であり、そして0説明しにくい場合は、最初の番号場合は前記最外層として、第一サイクル数P1内を
:ステップ3を、中間ポインタP2、テールポインタP3を定義
- NUM場合[P2] + [P3]> -nums [P1]、および説明が小さすぎると、大きな値NUM方向、P2に移動されなければならない++
- NUM [P2] + NUM [P3] <-nums [P1]、及びその後も、移動の方向であるため小さな値、p3--になら
- 中央へP2、P3が移動しながらNUM [P2] + NUM [P3] = -nums [P1]、結果は、結果の一意性を保証するために、保存されている場合、反復要素をスキップすることが必要です
C ++
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int> > resVec;
sort(nums.begin(),nums.end()); //将nums从小到大排序
for(int p1=0;p1<nums.size();p1++){
if(nums[p1] >0) //如果第一个数为正数,说明肯定不存在三个数
return resVec;
if(p1>0 && nums[p1] == nums[p1-1]) //由于结果需要唯一性,故去除nums中的重复元素
continue;
int p2 = p1+1;//中间指针
int p3 = nums.size()-1;//尾指针
while(p2<p3){
int a = nums[p1];//非正
int b = nums[p2];
int c = nums[p3];
if(b+c== -a){
vector<int> tempVec(3);
tempVec[0] = a;
tempVec[1] = b;
tempVec[2] = c;
resVec.push_back(tempVec);
while (p2 < p3 && nums[p2] == nums[p2 + 1]) //去除重复元素
p2++;
while (p2 < p3 && nums[p3 - 1] == nums[p3]) //去除重复元素
p3--;
p2++;
p3--;
}
else if(b+c < -a){ //如果b+c之和小于-a,说明和太小了,应该往数值大的方向的移动
p2++;
}
else{ //反之,如果b+c之和大于-a,说明和太大了,应该往数值小的方向的移动
p3--;
}
}
}
return resVec;
}