三数之和(大白话说思路)——数组专题
再解说这题解法之前,先解决一个问题,如何当有序递增数组有重复元素时,如何找到第一个比当前元素大的数,代码如下。
//当前数为 i
int index = i;
while(index<nums.size()&&nums[index]==nums[i])index++;
i = index;
思路:双指针,首先排序数组,遍历数组对于每一个元素nums[i]之后的数组做目标值为-nums[i]的两数之和。重要的是无论是双指针内部还是大循环中都需要在每次操作后找到第一个比当前大的数进行下一轮操作,而不是简单的++或- -,否则可能重复遍历导致时间复杂度升高。
class Solution {
public:
// 对于当前数 找-nums[i]的两数之和返回值
vector<vector<int>> threeSum(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<vector<int>>v;
for(int i=0;i<nums.size();){
int start = i+1;
if(start>=nums.size())break;
int end = nums.size()-1;
int target = -nums[i];
for(int j=start,k=nums.size()-1;j<k;){
if(nums[j] + nums[k]==target){
v.push_back({nums[i],nums[j],nums[k]});
//找到下一个比当前大的数
int index = j;
while(index<nums.size()&&nums[index]==nums[j])index++;
j = index ;
}
else if(nums[j] + nums[k]<target){
//找到下一个比当前大的数
int index = j;
while(index<nums.size()&&nums[index]==nums[j])index++;
j = index;
}
else {
//找到下一个比当前大的数
int index = k;
while(index>=0&&nums[index]==nums[k])index--;
k = index ;
}
}
//找到下一个比当前小的数
int index = i;
while(index<nums.size()&&nums[index]==nums[i])index++;
i = index ;
}
return v;
}
};