题目:
思路:
两数之和可以用双指针的方法解决,而三数之和只需要固定当前数字,即可转换为两数之和,这样的大思路并不难想到,此题主要是一些细节的处理与优化具有一定难度
- 去重:对数组nums进行排序,在nums[i]之后的有序序列中进行寻找,如果nums[i]==nums[i-1],那么这个解就是重复的,需要跳过(注意不能用nums[i]==nums[i+1]作为判断条件)。
- 若nums[I]>0,那么nums[i]之后所有的数全都大于零,他们的和不可能等于零,此时没有必要继续循环了,直接return。
- 在对当前的固定数nums[i]进行了去重之后,在循环内部还要对start和end指向的数字再进行一次去重。
代码:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> ans;
vector<int> v;
sort(nums.begin(),nums.end());
if(nums.size()<3) return ans;
for(int i=0;i<nums.size();i++){
if(i>0&&nums[i]==nums[i-1]) continue;//跳过重复的解
int start=i+1,end=nums.size()-1;
if(nums[i]>0) return ans;//其之后均大于零,已经无解
while(start<end){
if(nums[i]+nums[start]+nums[end]==0){
v.push_back(nums[i]);
v.push_back(nums[start]);
v.push_back(nums[end]);
ans.push_back(v);
v.clear();
while(start<end&&nums[start]==nums[start+1]) start++;//start<end很重要
while(start<end&&nums[end]==nums[end-1]) end--;
start++;
end--;
}
else if(nums[i]+nums[start]+nums[end]<0)
start++;
else
end--;
}
}
return ans;
}
};