题目要求:
给定一个包括 n 个整数的数组 nums
和 一个目标值 target
。找出 nums
中的三个整数,使得它们的和与 target
最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
C++代码:
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int n = nums.size();
sort(nums.begin(), nums.end());
int diff = INT_MAX;
int ans;
for(int i = 0; i < n-2; i++)
{
int num_i = nums[i];
int l = i+1, r = n-1;
if (i > 0 && num_i > 0 && num_i > target) return ans;
while(l < r)
{
int sum = num_i + nums[l] + nums[r];
if (diff > abs(sum - target))
{
ans = sum;
diff = abs(sum - target);
}
if (sum > target) r--;
else if (sum < target) l++;
else return sum;
}
}
return ans;
}
};
结果(8ms):
解析:
这题跟之前的第15题求三数之和基本一样的思路
多了一个判断当前的sum和target的差的过程而已,因为我们要求最接近的三数之和,越接近越好
详细解释如下:
把nums里的元素个数赋给n
int n = nums.size();
然后对nums的元素排序
sort(nums.begin(), nums.end());
然后初始化最大的偏差,这里叫diff,为INT_MAX
int diff = INT_MAX;
然后定义一个ans,就是最后返回的最接近的三数之和
int ans;
然后就是遍历每一个元素,从左到右,已经排好序的,和第15题一样,只遍历到n-2
for(int i = 0; i < n-2; i++)
首先把第一个元素的值赋给num_i
int num_i = nums[i];
然后跟第15题一样,第二个元素取第一个元素的下一位,第三个元素取最后一个元素
int l = i+1, r = n-1;
如果第一个元素都比target大了,那么越加后面的元素,总和越大,直接返回ans即可,ans此时为空
if (i > 0 && num_i > 0 && num_i > target) return ans;
否则,只要l<r,就执行while循环
while(l < r)
计算当前的三数之和sum
int sum = num_i + nums[l] + nums[r];
如果当前的sum和target之差的绝对值abs(sum - target),比前一次的diff小的话,那么我们就需要更新ans和diff
ans更新为当前的sum
diff更新为当前的sum和target之差的绝对值abs(sum - target)
if (diff > abs(sum - target))
{
ans = sum;
diff = abs(sum - target);
}
然后我们还需要判断我们当前的sum和target直接的关系,看到底是比target大还是比target小,我们好对第二个和第三个元素的位置进行更新,具体还是和第15题一样
if (sum > target) r--;
else if (sum < target) l++;
else return sum;
最后注意,该题返回的是int类型的,也就是最接近的三数之和,不需要三个元素,因此最后return ans; 即可