此题我们利用双指针完成:
先排序
在数组中,左指针j++和右指针k--,向中心靠齐;
不断更新,遍历数组全部元素;
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
//先排序
sort(nums.begin(),nums.end());
int n = nums.size();
// best=10,000,000
int best = 1e7;
// 定义一个lambda函数更新
auto update = [&](int cur){
if(abs(cur - target) < abs(best-target)){
best = cur;
}
};
// 枚举a
for(int i=0;i<n;i++){
// 保证和上一次枚举的元素不相等
if(i>0 && nums[i] == nums[i-1]){
continue;
}
// 使用双指针枚举 b 和 c
int j =i+1,k=n-1;
while(j<k){
int sum = nums[i] +nums[j]+nums[k];
if(sum == target){
return target;
}
update(sum);
//两个情况sum>target移动右指针
// sum<target移动左指针
if(sum>target){
// 如果和大于 target,移动 c 对应的指针
int k0 = k-1;
// 移动到下一个不相等k下标的元素
while(j<k0 && nums[k0] == nums[k]){
k0--;
}
k=k0;
}else{
// 移动左指针
int j0 = j+1;
// 移动到下一个等于j下标的元素
while(j0 < k && nums[j0] == nums[j]){
j0++;
}
j = j0;
}
}
}
return best;
}
};
时间复杂度O(n^2)
空间复杂度O(logN)