#include<iostream>
using namespace std;
#include<algorithm>
#include<cmath>
#include<vector>
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int res=-10086,mark=0,front,back,old_num=10086,nl=nums.size(); //res初始化为一个特殊的数,防止下面第一次交换会产生错误!
sort(nums.begin(),nums.end()); //排序,,,这类题的一个套路!
for(int i=0;i<nl;i++)
{
if(old_num==nums[i]) continue; //相同的第一个元素可以跳过,减少运行时间!
else old_num=nums[i];
mark=target-old_num; //用mark记录下target-old_num,等一下只要用双指针从两边向中间夹就能找出和mark最相近的差值!
front=i+1; //左边的指针!
back=nl-1; //右边的指针!
while(front<back)
{
res=abs(nums[front]+nums[back]-mark)>abs(res)?res:nums[front]+nums[back]-mark; //不断交换res,使得最后的res是和mark最相近的差值(比较时要用绝对值,赋值时要带上正负号)!
if(nums[front]+nums[back]>mark) back--; //if(nums[front]+nums[back]>mark),移动左指针!
else front++; //else,移动右指针!
}
}
return target+res; //返回目标数(target)加上差值,注意这里的差值(res)是带正负号的,因为要求的是真正的数!
}
};
刷题总结:
这个题是3sum的一个延伸,其实和3sum是一个思想,就是 “排序+双指针”,不过这里要注意题目是要求求最近目标的三数之和,所以无法直接求出结果,要用res做一个最小差值的不断转化(这里要用绝对值),最后得到的res是和target最小的差值(这里带正负号),最后用target+res就能得到最终的结果!