題目介紹
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)
解法
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
std::sort(nums.begin(), nums.end());
for(int i=0;i<nums.size();i++){
int front=i+1;
int j=nums.size()-1;
while(front<j){
if(nums[i]+nums[front]+nums[j]<0){
front++;
}else if(nums[i]+nums[front]+nums[j]==0){
vector<int> v(3,0);
v[0] = nums[i];
v[1] = nums[front];
v[2] = nums[j];
res.push_back(v);
while (front<j&&nums[front] == v[1]) front++;
while(front <j&&nums[j]==v[2]) j--;
}else{
j--;
}
// avoid time limited;
while(i+1<nums.size()&& nums[i]==nums[i+1]) i++;
}
}
return res;
}
思路
- 外循環使用變量i表示當前元素,front=i+1; j=nums.size()-1雙指針控制front, j分別代表頭部和尾部;
- 判斷nums[i]+nums[front]+nums[j]與0的關係:
- 當nums[i]+nums[front]+nums[j] < 0;表示負數,front需要後移;
- 當nums[i]+nums[front]+nums[j] == 0;保存結果;
- 當nums[i]+nums[front]+nums[j] > 0; 表示結果爲正,j需要前移。
- 在步驟2中要保證front < j.
總結
- 使用兩個指針夾逼控制判斷;
- 在遍歷的時候,開始都需要對雙指針進行賦值,而不是在循環中直接轉移,比如[-1,-1,0,-2,2],對於尾部指針可能存在[-2,0,2],[-1,-1,2];
- 之前測試中,出現時間超時,應該在遍歷時對於雙指針臨近有相同元素值的時候直接跳過,加快時間。
- 在判斷過程中保證front < j