双指针
快排使 n u m s nums nums 正序。
设置三个指针 i i i 指向 n u m s nums nums 第一个数,从前往后枚举 n u m s [ i ] nums[i] nums[i] , l l l 从 n u m s [ i + 1 ] nums[i+1] nums[i+1] 往后,指向第二个数, r r r 从 n u m s . s i z e ( ) − 1 nums.size()-1 nums.size()−1 往左,指向第三个数。
维护 a n s ans ans 变量,保存最接近的三数之和 。 设三数之和 n u m s [ i ] + n u m s [ l ] + n u m s [ r ] = s u m nums[i]+nums[l]+nums[r]=sum nums[i]+nums[l]+nums[r]=sum , 如果 ∣ s u m − t a r g e t ∣ > ∣ a n s − t a r g e t ∣ |sum-target|>|ans-target| ∣sum−target∣>∣ans−target∣ ,则 a n s ans ans 更新成 s u m sum sum 。
如果 s u m > t a r g e t sum>target sum>target ,为了接近 t a r g e t target target , r − − r-- r−− 。 同理, s u m < t a r g e t sum<target sum<target , 为了接近 t a r g e t target target , l + + l++ l++ 。
代码展示
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int n = nums.size();
int ans = INT_MAX/2;
for(int i = 0;i<n-2;i++){
for(int l = i+1,r = n-1;l<r;){
int sum = nums[i]+nums[l]+nums[r];
if (abs(ans-target)>abs(sum-target)) ans = sum;
if(sum>target) r--;
else if(sum<target) l++;
else return target;
}
}
return ans;
}
};
博主致语
理解思路很重要!
欢迎读者在评论区留言,作为日更博主,看到就会回复的。
AC
复杂度分析
- 时间复杂度: O ( n 2 ) O(n^2) O(n2), n n n 是 n u m s nums nums 的长度 , 枚举 n u m s [ i ] nums[i] nums[i] ,同时双指针枚举 n u m s [ l ] / n u m s [ r ] nums[l]/nums[r] nums[l]/nums[r] 的时间复杂度 O ( n 2 ) O(n^2) O(n2) 。
- 空间复杂度: O ( l o g n ) O(logn) O(logn),快排的平均空间复杂度 O ( l o g n ) O(logn) O(logn) 。