16. 最接近的三数之和
题目
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum-closest
示例
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
分析
与三数之和类似,先将数组变为升序数组,固定一个数 nums[i],用双指针从 nums[i] 后面的两端搜索,计算和值。如果与目标值相等,即此时的结果最接近目标值,直接返回;否则根据大小关系移动左右指针,更新结果值后进行下一次判断。
结果值的更新:
- 如果当前结果是拿到的第一个结果,直接将这个值赋给 res。这样做的目的是保证在没有与目标值相等的结果,并且 0 与目标值最为接近,但结果集中没有 0 值时,最终返回的结果不会是 res 的初始值 0。
- 否则,根据与目标值的接近程度更新结果值。
Code(Java)
class Solution {
public int threeSumClosest(int[] nums, int target) {
int res = 0;
boolean flag = false;
Arrays.sort(nums);
for(int i = 0; i < nums.length; i++) {
// 去重(优化)
if(i > 0 && nums[i] == nums[i-1]) {
continue;
}
// 定义双向指针
int l = i+1;
int r = nums.length-1;
while(l < r) { // 双向搜索
int sum = nums[i]+nums[l]+nums[r];
if(sum == target) { // 和值与目标值相等,即最接近目标值,直接返回
return sum;
}else if(sum > target) { // 否则根据大小关系移动左右指针
r--;
}else {
l++;
}
if(!flag) { // 拿到第一个和值,直接更新结果值并修改标志变量flag
res = sum;
flag = true;
}else if(flag && (Math.abs(sum-target) < Math.abs(res-target))) {
// 不是第一个和值,根据与目标值的接近程度更新结果值
res = sum;
}
}
}
return res;
}
}