给定一个包括 n 个整数的数组 nums
和 一个目标值 target
。找出 nums
中的三个整数,使得它们的和与 target
最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
思考:和15.三数之和一样,双指针left和right来遍历数组,dif来记录一个初始差值(3个数的和与target)。有几点一开始没想清楚。
1、一开始我只保存了一个最小差值,然后发现做不出来,因为最接近相当于是一个绝对值运算,最后如果不保存3个数之和,根据绝对值的差异再去求三个数很复杂。
2、在判断指针移动的时候,思考错了,弄了比较长时间。
//if(closest >sum)
/*最接近的三数之和与当前三数和的比较,和指针怎么走向没关系汗...
应该:当前的三数之和sum 和 target 比较就行了啊*/
if(sum > target)
right--;
else
left++;
}
3、判断循环次数的条件:这次用的数组总元素减去2个,相当于肯定你选3个数,当前的和 left 和 right。正好。可是以前为啥都用nums.size()?没太懂,因为这个时间复杂度基本不影响(额多循环2次还是有影响),就没管了。。还是写这次的写法。
for(int i = 0; i< nums.size() -2 ;i++) 这次写法
// for(int i = 0; i< nums.size() ;i++) 以前的写法
代码:
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end());
int closest = nums[0] + nums[1]+nums[2];
int dif = abs(closest - target);
for(int i = 0; i< nums.size()-2;i++){
int left = i+1,right = nums.size()-1;
while(left < right){
int sum = nums[i] + nums[left] + nums[right];
int new_dif = abs(sum- target);
if(new_dif < dif){
closest = sum;
dif = new_dif;
}
//if(closest >sum)
if(sum > target)
right--;
else
left++;
}
}
return closest;
}
};